12 Commits

Author SHA1 Message Date
ea7e693759 Merge pull request 'liquidation pour une parcelle' (#208) from features/fiche_refonte into develop
Reviewed-on: #208
2026-04-30 16:04:27 +00:00
ae2f5bd188 liquidation pour une parcelle
All checks were successful
CI - Build & Test (develop) / build-and-test (pull_request) Successful in 29s
2026-04-30 17:03:51 +01:00
6b954c7467 Merge pull request 'liquidation pour une parcelle' (#206) from features/fiche_refonte into develop
Reviewed-on: #206
2026-04-30 10:32:29 +00:00
71e566da25 liquidation pour une parcelle
All checks were successful
CI - Build & Test (develop) / build-and-test (pull_request) Successful in 34s
2026-04-30 11:31:58 +01:00
2b2805a125 Merge pull request 'liquidation pour une parcelle' (#204) from features/fiche_refonte into develop
Reviewed-on: #204
2026-04-24 15:46:11 +00:00
fc82e6b1df liquidation pour une parcelle
All checks were successful
CI - Build & Test (develop) / build-and-test (pull_request) Successful in 28s
2026-04-24 16:45:38 +01:00
49aea6e50a Merge pull request 'liquidation pour une parcelle' (#202) from features/fiche_refonte into develop
Reviewed-on: #202
2026-04-24 13:53:38 +00:00
ec991b7df9 liquidation pour une parcelle
All checks were successful
CI - Build & Test (develop) / build-and-test (pull_request) Successful in 37s
2026-04-24 14:51:28 +01:00
3e105855f0 Merge pull request 'centre assignation et parcelle de contact' (#200) from features/fiche_refonte into develop
Reviewed-on: #200
2026-04-10 14:08:13 +00:00
03f38dfe1c centre assignation et parcelle de contact
All checks were successful
CI - Build & Test (develop) / build-and-test (pull_request) Successful in 37s
2026-04-10 15:06:22 +01:00
5b73474192 Merge pull request 'centre assignation' (#198) from features/fiche_refonte into develop
Reviewed-on: #198
2026-04-01 20:03:57 +00:00
9a91961484 centre assignation
All checks were successful
CI - Build & Test (develop) / build-and-test (pull_request) Successful in 28s
2026-04-01 21:03:26 +01:00
51 changed files with 6529 additions and 1300 deletions

View File

@@ -0,0 +1,314 @@
package io.gmss.fiscad.controllers.rfu.metier;
import io.gmss.fiscad.entities.user.User;
import io.gmss.fiscad.exceptions.*;
import io.gmss.fiscad.implementations.infocad.metier.PersonneServiceImpl;
import io.gmss.fiscad.interfaces.rfu.metier.CommuneCentreAssignationService;
import io.gmss.fiscad.paylaods.ApiResponse;
import io.gmss.fiscad.paylaods.request.crudweb.CommuneCentreAssignationPaylaodWeb;
import io.gmss.fiscad.security.CurrentUser;
import io.gmss.fiscad.security.UserPrincipal;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.HttpClientErrorException;
@RestController
@AllArgsConstructor
@RequestMapping(value = "api/commune-centre-assignation", produces = MediaType.APPLICATION_JSON_VALUE)
@SecurityRequirement(name = "bearer")
@Tag(name = "CommuneCentreAssignation")
@CrossOrigin(origins = "*")
public class CommuneCentreAssignationController {
private final CommuneCentreAssignationService communeCentreAssignationService;
private final PersonneServiceImpl personneService;
private static final Logger logger = LoggerFactory.getLogger(CommuneCentreAssignationController.class);
// public CommuneCentreAssignationController(CommuneCentreAssignationService communeCentreAssignationService) {
// this.communeCentreAssignationService = communeCentreAssignationService;
// }
@PostMapping("/assigne-centre")
public ResponseEntity<?> AssigneCommuneCentre(@CurrentUser UserPrincipal userPrincipal, @RequestBody CommuneCentreAssignationPaylaodWeb communeCentreAssignationPaylaodWeb) {
try {
if(userPrincipal==null){
return new ResponseEntity<>(
new ApiResponse<>(false, null, "vous ne pouvez pas faire cette action."),
HttpStatus.OK
);
}
User user = userPrincipal.getUser();
communeCentreAssignationPaylaodWeb = communeCentreAssignationService.createCommuneCentreAssignation(user,communeCentreAssignationPaylaodWeb);
return new ResponseEntity<>(
new ApiResponse<>(true, communeCentreAssignationPaylaodWeb, "CommuneCentreAssignation créé avec succès."),
HttpStatus.OK
);
} catch (HttpClientErrorException.MethodNotAllowed e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "Method POST/GET is required."), HttpStatus.OK);
} catch (NotFoundException | BadRequestException | MyFileNotFoundException | ResourceNotFoundException |
FileStorageException e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, e.getMessage()), HttpStatus.OK);
} catch (NullPointerException e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "Null value has been detected {" + e.getMessage() + "}."), HttpStatus.OK);
} catch (Exception e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "An error has been occur and the content is {" + e.getMessage() + "}."), HttpStatus.OK);
}
}
@PostMapping("/detache-centre")
public ResponseEntity<?> detacheCommuneCentre(@CurrentUser UserPrincipal userPrincipal, @RequestBody CommuneCentreAssignationPaylaodWeb communeCentreAssignationPaylaodWeb) {
try {
if(userPrincipal==null){
return new ResponseEntity<>(
new ApiResponse<>(false, null, "vous ne pouvez pas faire cette action."),
HttpStatus.OK
);
}
User user = userPrincipal.getUser();
communeCentreAssignationPaylaodWeb = communeCentreAssignationService.detacherCommuneCentreAssignation(user,communeCentreAssignationPaylaodWeb);
return new ResponseEntity<>(
new ApiResponse<>(true, communeCentreAssignationPaylaodWeb, "CommuneCentreAssignation créé avec succès."),
HttpStatus.OK
);
} catch (HttpClientErrorException.MethodNotAllowed e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "Method POST/GET is required."), HttpStatus.OK);
} catch (NotFoundException | BadRequestException | MyFileNotFoundException | ResourceNotFoundException |
FileStorageException e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, e.getMessage()), HttpStatus.OK);
} catch (NullPointerException e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "Null value has been detected {" + e.getMessage() + "}."), HttpStatus.OK);
} catch (Exception e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "An error has been occur and the content is {" + e.getMessage() + "}."), HttpStatus.OK);
}
}
@PutMapping("/update/{id}")
public ResponseEntity<?> updateCommuneCentreAssignation(@PathVariable Long id, @RequestBody CommuneCentreAssignationPaylaodWeb communeCentreAssignationPaylaodWeb) {
try {
return new ResponseEntity<>(
new ApiResponse<>(true, communeCentreAssignationService.updateCommuneCentreAssignation(id,communeCentreAssignationPaylaodWeb), "CommuneCentreAssignation mise à jour avec succès."),
HttpStatus.OK
);
} catch (HttpClientErrorException.MethodNotAllowed e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "Method POST/GET is required."), HttpStatus.OK);
} catch (NotFoundException | BadRequestException | MyFileNotFoundException | ResourceNotFoundException |
FileStorageException e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, e.getMessage()), HttpStatus.OK);
} catch (NullPointerException e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "Null value has been detected {" + e.getMessage() + "}."), HttpStatus.OK);
} catch (Exception e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "An error has been occur and the content is {" + e.getMessage() + "}."), HttpStatus.OK);
}
}
@DeleteMapping("/delete/{id}")
public ResponseEntity<?> deleteCommuneCentreAssignation(@PathVariable Long id) {
try {
communeCentreAssignationService.deleteCommuneCentreAssignation(id);
return new ResponseEntity<>(
new ApiResponse<>(true, "CommuneCentreAssignation supprimée avec succès."),
HttpStatus.OK
);
} catch (HttpClientErrorException.MethodNotAllowed e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "Method POST/GET is required."), HttpStatus.OK);
} catch (NotFoundException | BadRequestException | MyFileNotFoundException | ResourceNotFoundException |
FileStorageException e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, e.getMessage()), HttpStatus.OK);
} catch (NullPointerException e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "Null value has been detected {" + e.getMessage() + "}."), HttpStatus.OK);
} catch (Exception e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "An error has been occur and the content is {" + e.getMessage() + "}."), HttpStatus.OK);
}
}
@GetMapping("/all-paged")
public ResponseEntity<?> getAllCommuneCentreAssignationPaged(@RequestParam int pageNo, @RequestParam int pageSize) {
try {
Pageable pageable = PageRequest.of(pageNo, pageSize);
return new ResponseEntity<>(
new ApiResponse<>(true, communeCentreAssignationService.getCommuneCentreAssignationList(pageable), "Liste des caractéristiques chargée avec succès."),
HttpStatus.OK
);
} catch (HttpClientErrorException.MethodNotAllowed e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "Method POST/GET is required."), HttpStatus.OK);
} catch (NotFoundException | BadRequestException | MyFileNotFoundException | ResourceNotFoundException |
FileStorageException e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, e.getMessage()), HttpStatus.OK);
} catch (NullPointerException e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "Null value has been detected {" + e.getMessage() + "}."), HttpStatus.OK);
} catch (Exception e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "An error has been occur and the content is {" + e.getMessage() + "}."), HttpStatus.OK);
}
}
@GetMapping("/all-paged/by-commune-id/{communeId}")
public ResponseEntity<?> getAllCommuneCentreAssignationByCommuneList(@PathVariable Long communeId,@RequestParam int pageNo, @RequestParam int pageSize ) {
try {
Pageable pageable = PageRequest.of(pageNo, pageSize);
return new ResponseEntity<>(
new ApiResponse<>(true, communeCentreAssignationService.getCommuneCentreAssignationListByCommunePageable(communeId,pageable), "Liste des assignation de centre chargée avec succès."),
HttpStatus.OK
);
} catch (HttpClientErrorException.MethodNotAllowed e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "Method POST/GET is required."), HttpStatus.OK);
} catch (NotFoundException | BadRequestException | MyFileNotFoundException | ResourceNotFoundException |
FileStorageException e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, e.getMessage()), HttpStatus.OK);
} catch (NullPointerException e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "Null value has been detected {" + e.getMessage() + "}."), HttpStatus.OK);
} catch (Exception e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "An error has been occur and the content is {" + e.getMessage() + "}."), HttpStatus.OK);
}
}
@GetMapping("/id/{id}")
public ResponseEntity<?> getCommuneCentreAssignationById(@PathVariable Long id) {
try {
return new ResponseEntity<>(
new ApiResponse<>(true, communeCentreAssignationService.getCommuneCentreAssignationById(id), "CommuneCentreAssignation trouvée avec succès."),
HttpStatus.OK
);
} catch (HttpClientErrorException.MethodNotAllowed e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "Method POST/GET is required."), HttpStatus.OK);
} catch (NotFoundException | BadRequestException | MyFileNotFoundException | ResourceNotFoundException |
FileStorageException e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, e.getMessage()), HttpStatus.OK);
} catch (NullPointerException e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "Null value has been detected {" + e.getMessage() + "}."), HttpStatus.OK);
} catch (Exception e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "An error has been occur and the content is {" + e.getMessage() + "}."), HttpStatus.OK);
}
}
@Operation(summary = "Liste des contribuables ayant un centre d'assignation")
@GetMapping("/all-paged/by-structure-id/{structureId}")
public ResponseEntity<?> getAllCommuneCentreAssignationByStrucutrePaged(@PathVariable Long structureId, @RequestParam int pageNo, @RequestParam int pageSize) {
try {
Pageable pageable = PageRequest.of(pageNo, pageSize);
return new ResponseEntity<>(
new ApiResponse<>(true, communeCentreAssignationService.getCommuneCentreAssignationListByCentrePageable(structureId, pageable), "Liste des communeCentreAssignations chargée avec succès."),
HttpStatus.OK
);
} catch (HttpClientErrorException.MethodNotAllowed e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "Method POST/GET is required."), HttpStatus.OK);
} catch (NotFoundException | BadRequestException | MyFileNotFoundException | ResourceNotFoundException |
FileStorageException e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, e.getMessage()), HttpStatus.OK);
} catch (NullPointerException e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "Null value has been detected {" + e.getMessage() + "}."), HttpStatus.OK);
} catch (Exception e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "An error has been occur and the content is {" + e.getMessage() + "}."), HttpStatus.OK);
}
}
@Operation(summary = "Liste des contribuables sans centre d'assignation")
@GetMapping("/all-paged/sans-centre-assignation")
public ResponseEntity<?> getAllPersonneSansCentreAssignationPaged(@RequestParam int pageNo, @RequestParam int pageSize) {
try {
Pageable pageable = PageRequest.of(pageNo, pageSize);
return new ResponseEntity<>(
new ApiResponse<>(true, personneService.getPersonneListNonAssigneePage(pageable), "Liste des contribuables sans centre d'assignation chargée avec succès."),
HttpStatus.OK
);
} catch (HttpClientErrorException.MethodNotAllowed e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "Method POST/GET is required."), HttpStatus.OK);
} catch (NotFoundException | BadRequestException | MyFileNotFoundException | ResourceNotFoundException |
FileStorageException e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, e.getMessage()), HttpStatus.OK);
} catch (NullPointerException e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "Null value has been detected {" + e.getMessage() + "}."), HttpStatus.OK);
} catch (Exception e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "An error has been occur and the content is {" + e.getMessage() + "}."), HttpStatus.OK);
}
}
@Operation(summary = "Vérifier l'assignation d'un contribuable",description = "permet de vérifier si un contribuable a déjà un centre d'assignation dans la commune de l'utilisateur connecté")
@GetMapping("/contribuable/{personneId}")
public ResponseEntity<?> getAssignationPersonne(@CurrentUser UserPrincipal currentUser, @PathVariable Long personneId) {
try {
if(currentUser==null){
return new ResponseEntity<>(
new ApiResponse<>(false, null, "vous ne pouvez pas faire cette action."),
HttpStatus.OK
);
}
User user = currentUser.getUser();
return new ResponseEntity<>(
new ApiResponse<>(true, communeCentreAssignationService.getCommuneCentreAssignationByPersonneIdCommune(user,personneId).orElse(null), "Assignation chargée avec succès."),
HttpStatus.OK
);
} catch (HttpClientErrorException.MethodNotAllowed e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "Method POST/GET is required."), HttpStatus.OK);
} catch (NotFoundException | BadRequestException | MyFileNotFoundException | ResourceNotFoundException |
FileStorageException e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, e.getMessage()), HttpStatus.OK);
} catch (NullPointerException e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "Null value has been detected {" + e.getMessage() + "}."), HttpStatus.OK);
} catch (Exception e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "An error has been occur and the content is {" + e.getMessage() + "}."), HttpStatus.OK);
}
}
}

View File

@@ -36,7 +36,7 @@ public class DeclarationNcController {
@PostMapping("/create") @PostMapping("/create")
public ResponseEntity<?> createDeclarationNc(@RequestBody @Valid @Validated DeclarationNcPayloadWeb declarationNcPayloadWeb) { public ResponseEntity<?> createDeclarationNc(@RequestBody DeclarationNcPayloadWeb declarationNcPayloadWeb) {
try { try {
declarationNcPayloadWeb = declarationNcService.createDeclarationNc(declarationNcPayloadWeb); declarationNcPayloadWeb = declarationNcService.createDeclarationNc(declarationNcPayloadWeb);
return new ResponseEntity<>( return new ResponseEntity<>(

View File

@@ -116,52 +116,52 @@ public class DonneesImpositionTfuController {
} }
} }
@GetMapping("/all") // @GetMapping("/all")
public ResponseEntity<?> getAllDonneesImpositionTfuList() { // public ResponseEntity<?> getAllDonneesImpositionTfuList() {
try { // try {
return new ResponseEntity<>( // return new ResponseEntity<>(
new ApiResponse<>(true, donneesImpositionTfuService.getDonneesImpositionTfuList(), "Liste des impositions chargée avec succès."), // new ApiResponse<>(true, donneesImpositionTfuService.getDonneesImpositionTfuList(), "Liste des impositions chargée avec succès."),
HttpStatus.OK // HttpStatus.OK
); // );
} catch (HttpClientErrorException.MethodNotAllowed e) { // } catch (HttpClientErrorException.MethodNotAllowed e) {
logger.error(e.getLocalizedMessage()); // logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "Method POST/GET is required."), HttpStatus.OK); // return new ResponseEntity<>(new ApiResponse(false, null, "Method POST/GET is required."), HttpStatus.OK);
} catch (NotFoundException | BadRequestException | MyFileNotFoundException | ResourceNotFoundException | // } catch (NotFoundException | BadRequestException | MyFileNotFoundException | ResourceNotFoundException |
FileStorageException e) { // FileStorageException e) {
logger.error(e.getLocalizedMessage()); // logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, e.getMessage()), HttpStatus.OK); // return new ResponseEntity<>(new ApiResponse(false, null, e.getMessage()), HttpStatus.OK);
} catch (NullPointerException e) { // } catch (NullPointerException e) {
logger.error(e.getLocalizedMessage()); // logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "Null value has been detected {" + e.getMessage() + "}."), HttpStatus.OK); // return new ResponseEntity<>(new ApiResponse(false, null, "Null value has been detected {" + e.getMessage() + "}."), HttpStatus.OK);
} catch (Exception e) { // } catch (Exception e) {
logger.error(e.getLocalizedMessage()); // logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "An error has been occur and the content is {" + e.getMessage() + "}."), HttpStatus.OK); // return new ResponseEntity<>(new ApiResponse(false, null, "An error has been occur and the content is {" + e.getMessage() + "}."), HttpStatus.OK);
} // }
} // }
@GetMapping("/all-paged") // @GetMapping("/all-paged")
public ResponseEntity<?> getAllDonneesImpositionTfuPaged(@RequestParam int pageNo, @RequestParam int pageSize) { // public ResponseEntity<?> getAllDonneesImpositionTfuPaged(@RequestParam int pageNo, @RequestParam int pageSize) {
try { // try {
Pageable pageable = PageRequest.of(pageNo, pageSize); // Pageable pageable = PageRequest.of(pageNo, pageSize);
return new ResponseEntity<>( // return new ResponseEntity<>(
new ApiResponse<>(true, donneesImpositionTfuService.getDonneesImpositionTfuList(pageable), "Liste des impositions chargée avec succès."), // new ApiResponse<>(true, donneesImpositionTfuService.getDonneesImpositionTfuList(pageable), "Liste des impositions chargée avec succès."),
HttpStatus.OK // HttpStatus.OK
); // );
} catch (HttpClientErrorException.MethodNotAllowed e) { // } catch (HttpClientErrorException.MethodNotAllowed e) {
logger.error(e.getLocalizedMessage()); // logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "Method POST/GET is required."), HttpStatus.OK); // return new ResponseEntity<>(new ApiResponse(false, null, "Method POST/GET is required."), HttpStatus.OK);
} catch (NotFoundException | BadRequestException | MyFileNotFoundException | ResourceNotFoundException | // } catch (NotFoundException | BadRequestException | MyFileNotFoundException | ResourceNotFoundException |
FileStorageException e) { // FileStorageException e) {
logger.error(e.getLocalizedMessage()); // logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, e.getMessage()), HttpStatus.OK); // return new ResponseEntity<>(new ApiResponse(false, null, e.getMessage()), HttpStatus.OK);
} catch (NullPointerException e) { // } catch (NullPointerException e) {
logger.error(e.getLocalizedMessage()); // logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "Null value has been detected {" + e.getMessage() + "}."), HttpStatus.OK); // return new ResponseEntity<>(new ApiResponse(false, null, "Null value has been detected {" + e.getMessage() + "}."), HttpStatus.OK);
} catch (Exception e) { // } catch (Exception e) {
logger.error(e.getLocalizedMessage()); // logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "An error has been occur and the content is {" + e.getMessage() + "}."), HttpStatus.OK); // return new ResponseEntity<>(new ApiResponse(false, null, "An error has been occur and the content is {" + e.getMessage() + "}."), HttpStatus.OK);
} // }
} // }
@GetMapping("/all-page/by-imposition-id/{impositionId}") @GetMapping("/all-page/by-imposition-id/{impositionId}")
@@ -333,6 +333,59 @@ public class DonneesImpositionTfuController {
} }
@Operation(
summary = "Générer les données fiscales TFU pour une seule parcelle",
description = "Génère les impositions TFU pour une parcelle bâtie donnée"
)
@PostMapping("/generer-batie/{parcelleId}")
public ResponseEntity<?> genererDonneesFiscaleBatieUneParcelle(@CurrentUser UserPrincipal userPrincipal, @RequestBody ImpositionsTfuPaylaodWeb impositionsTfuPaylaodWeb,@PathVariable Long parcelleId) {
try {
Optional<ImpositionsTfu> optionalImpositionsTfu =impositionsTfuRepository.findById(impositionsTfuPaylaodWeb.getId());
if(optionalImpositionsTfu.isEmpty()){
return new ResponseEntity<>(
new ApiResponse<>(false, null, "L'instance d'imposition n'est pas trouvée."),
HttpStatus.OK
);
}
// if(!optionalImpositionsTfu.get().getStatusAvis().equals(StatusAvis.TFU_FNB_GENERE)){
// return new ResponseEntity<>(
// new ApiResponse<>(false, null, "l'état actuel : "+optionalImpositionsTfu.get().getStatusAvis()+" ne permet pas cette opération."),
// HttpStatus.OK
// );
// }
if(userPrincipal==null){
return new ResponseEntity<>(
new ApiResponse<>(false, null, "Vous n'êtes pas autorisé à accéder à cette ressource"),
HttpStatus.OK
);
}
impositionsTfuPaylaodWeb=donneesImpositionTfuService.genererDonneesFiscalesParcelleBatieUneParcelle(impositionsTfuPaylaodWeb,userPrincipal.getUser().getId(),parcelleId);
return new ResponseEntity<>(
new ApiResponse<>(true,impositionsTfuPaylaodWeb, "Données d'imposition des fonciers batis Générées avec succès."),
HttpStatus.OK
);
} catch (HttpClientErrorException.MethodNotAllowed e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "Method POST/GET is required."), HttpStatus.OK);
} catch (NotFoundException | BadRequestException | MyFileNotFoundException | ResourceNotFoundException |
FileStorageException e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, e.getMessage()), HttpStatus.OK);
} catch (NullPointerException e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "Null value has been detected {" + e.getMessage() + "}."), HttpStatus.OK);
} catch (Exception e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "An error has been occur and the content is {" + e.getMessage() + "}."), HttpStatus.OK);
}
}
@Operation(summary = "Générer les données fiscales TFU des parcelle baties") @Operation(summary = "Générer les données fiscales TFU des parcelle baties")
@@ -384,6 +437,59 @@ public class DonneesImpositionTfuController {
} }
} }
@Operation(
summary = "Générer les données fiscales TFU pour une seule parcelle",
description = "Génère les impositions TFU pour une parcelle non bâtie donnée"
)
@PostMapping("/generer-non-batie/{parcelleId}")
public ResponseEntity<?> genererDonneesImpositionNonBatiesUneParcelle(@CurrentUser UserPrincipal userPrincipal, @RequestBody ImpositionsTfuPaylaodWeb impositionsTfuPaylaodWeb, @PathVariable Long parcelleId) {
try {
Optional<ImpositionsTfu> optionalImpositionsTfu =impositionsTfuRepository.findById(impositionsTfuPaylaodWeb.getId());
if(optionalImpositionsTfu.isEmpty()){
return new ResponseEntity<>(
new ApiResponse<>(false, null, "L'instance d'imposition n'est pas trouvée."),
HttpStatus.OK
);
}
// if(!optionalImpositionsTfu.get().getStatusAvis().equals(StatusAvis.GENERATION_AUTORISE)){
// return new ResponseEntity<>(
// new ApiResponse<>(false, null, "l'état actuel : "+optionalImpositionsTfu.get().getStatusAvis()+" ne permet pas cette opération."),
// HttpStatus.OK
// );
// }
if(userPrincipal==null){
return new ResponseEntity<>(
new ApiResponse<>(false, null, "Vous n'êtes pas autorisé à accéder à cette ressource"),
HttpStatus.OK
);
}
impositionsTfuPaylaodWeb=donneesImpositionTfuService.genererDonneesFiscalesParcelleNonBatieUneParcelle(impositionsTfuPaylaodWeb,userPrincipal.getUser().getId(),parcelleId);
return new ResponseEntity<>(
new ApiResponse<>(true,impositionsTfuPaylaodWeb, "Données d'imposition pour les fonciers non batis Générées avec succès."),
HttpStatus.OK
);
} catch (HttpClientErrorException.MethodNotAllowed e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "Method POST/GET is required."), HttpStatus.OK);
} catch (NotFoundException | BadRequestException | MyFileNotFoundException | ResourceNotFoundException |
FileStorageException e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, e.getMessage()), HttpStatus.OK);
} catch (NullPointerException e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "Null value has been detected {" + e.getMessage() + "}."), HttpStatus.OK);
} catch (Exception e) {
logger.error(e.getLocalizedMessage());
return new ResponseEntity<>(new ApiResponse(false, null, "An error has been occur and the content is {" + e.getMessage() + "}."), HttpStatus.OK);
}
}
@Operation(summary = "Récuperer les avis d'id d'une imposition") @Operation(summary = "Récuperer les avis d'id d'une imposition")
@GetMapping("/by-impositions-id/{impositionsId}") @GetMapping("/by-impositions-id/{impositionsId}")
public ResponseEntity<?> getDonneesFiscale(@PathVariable Long impositionsId) { public ResponseEntity<?> getDonneesFiscale(@PathVariable Long impositionsId) {

View File

@@ -41,6 +41,7 @@ public class Personne extends BaseEntity implements Serializable {
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; private Long id;
private String ifu; private String ifu;
private String nc;
private String nom; private String nom;
private String prenom; private String prenom;
private String raisonSociale; private String raisonSociale;

View File

@@ -0,0 +1,62 @@
package io.gmss.fiscad.entities.interface_sigibe;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import io.gmss.fiscad.deserializer.LocalDateDeserializer;
import io.gmss.fiscad.entities.BaseEntity;
import io.gmss.fiscad.entities.decoupage.Quartier;
import io.gmss.fiscad.entities.infocad.parametre.Personne;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.LocalDate;
@EqualsAndHashCode(callSuper = true)
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class DeclarationSpontaneBien extends BaseEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Long idImposition ;
private String rImposition ;
private String ifu ;
private String rCommune ;
private String rQuartier ;
private String qipQuartier;
private String qipIlot;
private String qipParcelle;
private String nup;
private String gpsLatitude;
private String gpsLongitude;
private String commentaire;
@JsonFormat(pattern = "dd-MM-yyyy")
@JsonDeserialize(using = LocalDateDeserializer.class)
private LocalDate dateValidation;
@JsonFormat(pattern = "dd-MM-yyyy")
@JsonDeserialize(using = LocalDateDeserializer.class)
private LocalDate dateInformation;
private Long valeurBatiment;
private Long nub;
private Long nul;
private Long montantLocatifAnnuel ;
@JsonFormat(pattern = "dd-MM-yyyy")
@JsonDeserialize(using = LocalDateDeserializer.class)
private LocalDate dateConstruction;
private Float superficieSolBat;
private Float superficieSolUlot;
private Float superficieParcelle;
private String usage;
private Boolean bati;
@ManyToOne
private Personne personne;
@ManyToOne
private Quartier quartier;
}

View File

@@ -0,0 +1,58 @@
package io.gmss.fiscad.entities.interface_sigibe;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import io.gmss.fiscad.deserializer.LocalDateDeserializer;
import io.gmss.fiscad.entities.BaseEntity;
import io.gmss.fiscad.entities.infocad.parametre.Personne;
import io.gmss.fiscad.entities.infocad.parametre.PositionRepresentation;
import io.gmss.fiscad.entities.infocad.parametre.TypeContestation;
import io.gmss.fiscad.entities.infocad.parametre.TypeRepresentation;
import io.gmss.fiscad.enums.SourceDonnee;
import io.gmss.fiscad.enums.TypeDroit;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.LocalDate;
@EqualsAndHashCode(callSuper = true)
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class EpaiementAcompte extends BaseEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Long idPaiementAcompte;
private Long idPaiementImpot;
private String rDoc;
private String rImpot;
private String idImpotType;
private String idImpotNature;
private String ifu;
private String rCommune;
private String rQuartier;
private String qipQuartier;
private String qipIlot;
private String qipParcelle;
private String nup;
private Long exercice;
@JsonFormat(pattern = "dd-MM-yyyy")
@JsonDeserialize(using = LocalDateDeserializer.class)
private LocalDate dateValidation;
@JsonFormat(pattern = "dd-MM-yyyy")
@JsonDeserialize(using = LocalDateDeserializer.class)
private LocalDate dateAvisCredit;
@JsonFormat(pattern = "dd-MM-yyyy")
@JsonDeserialize(using = LocalDateDeserializer.class)
private LocalDate dateRapprochement;
@JsonFormat(pattern = "dd-MM-yyyy")
@JsonDeserialize(using = LocalDateDeserializer.class)
private LocalDate dateInformation;
private Long montantPayer;
}

View File

@@ -0,0 +1,55 @@
package io.gmss.fiscad.entities.interface_sigibe;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import io.gmss.fiscad.deserializer.LocalDateDeserializer;
import io.gmss.fiscad.entities.BaseEntity;
import io.gmss.fiscad.enums.SourceDonnee;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.LocalDate;
@EqualsAndHashCode(callSuper = true)
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class EpaiementRetenu extends BaseEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Long idPaiementRetenue;
private Long idEdiGenerique;
private Long idPaiementImpot;
private String rDoc;
private String rImpot;
private String idImpotType;
private String idImpotNature;
private String ifuPayeur;
private String ifuRetenue;
private String rCommune;
private String rQuartier;
private String qipQuartier;
private String qipIlot;
private String qipParcelle;
private String nup;
private Long exercice;
@JsonFormat(pattern = "dd-MM-yyyy")
@JsonDeserialize(using = LocalDateDeserializer.class)
private LocalDate dateValidation;
@JsonFormat(pattern = "dd-MM-yyyy")
@JsonDeserialize(using = LocalDateDeserializer.class)
private LocalDate dateAvisCredit;
@JsonFormat(pattern = "dd-MM-yyyy")
@JsonDeserialize(using = LocalDateDeserializer.class)
private LocalDate dateRapprochement;
@JsonFormat(pattern = "dd-MM-yyyy")
@JsonDeserialize(using = LocalDateDeserializer.class)
private LocalDate dateInformation;
private Long montantPayer;
}

View File

@@ -0,0 +1,50 @@
package io.gmss.fiscad.entities.interface_sigibe;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import io.gmss.fiscad.deserializer.LocalDateDeserializer;
import io.gmss.fiscad.entities.BaseEntity;
import io.gmss.fiscad.enums.SourceDonnee;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.LocalDate;
@EqualsAndHashCode(callSuper = true)
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PaiementAvis extends BaseEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Long idPaiementImpot;
private Long idAvis;
private Long idUniteFoncier;
private Long idContribuableFoncier;
private String rDoc;
private String rImpot;
private String idImpotType;
private String idImpotNature;
private String ifu;
private String rCommune;
@JsonFormat(pattern = "dd-MM-yyyy")
@JsonDeserialize(using = LocalDateDeserializer.class)
private LocalDate dateValidation;
@JsonFormat(pattern = "dd-MM-yyyy")
@JsonDeserialize(using = LocalDateDeserializer.class)
private LocalDate dateAvisCredit;
@JsonFormat(pattern = "dd-MM-yyyy")
@JsonDeserialize(using = LocalDateDeserializer.class)
private LocalDate dateRapprochement;
@JsonFormat(pattern = "dd-MM-yyyy")
@JsonDeserialize(using = LocalDateDeserializer.class)
private LocalDate dateInformation;
private Long montantPayer;
}

View File

@@ -0,0 +1,67 @@
package io.gmss.fiscad.entities.rfu.metier;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import io.gmss.fiscad.deserializer.LocalDateDeserializer;
import io.gmss.fiscad.entities.BaseEntity;
import io.gmss.fiscad.entities.decoupage.Commune;
import io.gmss.fiscad.entities.infocad.metier.Parcelle;
import io.gmss.fiscad.entities.infocad.metier.Tpe;
import io.gmss.fiscad.entities.infocad.parametre.Personne;
import io.gmss.fiscad.entities.infocad.parametre.Structure;
import io.gmss.fiscad.enums.StatutEnregistrement;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.LocalDate;
@Entity
@Table(
uniqueConstraints = {
@UniqueConstraint(
name = "uk_structure_commune_personne",
columnNames = {"structure_id", "commune_id", "personne_id"}
)
}
)
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class CommuneCentreAssignation extends BaseEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@JsonIgnore
@ManyToOne
@JoinColumn(name = "structure_id", nullable = false)
private Structure structure;
@JsonIgnore
@ManyToOne
@JoinColumn(name = "commune_id", nullable = false)
private Commune commune;
@JsonIgnore
@ManyToOne
@JoinColumn(name = "personne_id")
private Personne personne;
@JsonIgnore
@ManyToOne
@JoinColumn(name = "parcelle_id")
private Parcelle parcelle;
private String nc;
private String ifu;
private String adresseContact ;
}

View File

@@ -36,19 +36,22 @@ public class DeclarationNc extends BaseEntity implements Serializable {
@JsonDeserialize(using = LocalDateDeserializer.class) @JsonDeserialize(using = LocalDateDeserializer.class)
private LocalDate dateDerniereDeclaration; private LocalDate dateDerniereDeclaration;
@JsonFormat(pattern = "yyyy-MM-dd") @JsonFormat(pattern = "yyyy-MM-dd")
@JsonDeserialize(using = LocalDateDeserializer.class) @JsonDeserialize(using = LocalDateDeserializer.class)
private LocalDate dateDeclarationNc; private LocalDate dateDeclarationNc;
private String nc; private String nc;
private String q;
private String i;
private String p;
private String numeroTitreFoncier;
private String nup;
private String observation; private String observation;
@JsonIgnore @JsonIgnore
@ManyToOne @ManyToOne
private Structure structure; private Structure structure;
private Long enqueteExternalKey; private Long enqueteExternalKey;
@JsonIgnore @JsonIgnore

View File

@@ -114,6 +114,11 @@ public class DonneesImpositionTfu extends BaseEntity implements Serializable {
private Float tauxTfu; private Float tauxTfu;
private Long tfuPiscine; private Long tfuPiscine;
private Float montantTaxe; private Float montantTaxe;
private Float penalite;
private Float retenuIrf ;
private Float acompte ;
private Float montantRestant ;
private Float montantTaxeBrut; //montant de la taxe calculée sans comparaisons avec TFU MINI
private Float tfuCalculeTauxPropParc; private Float tfuCalculeTauxPropParc;
private Float tfuSuperficieAuSolReel; private Float tfuSuperficieAuSolReel;
private Long valeurAdminParcelleNbMetreCarre; private Long valeurAdminParcelleNbMetreCarre;
@@ -146,5 +151,6 @@ public class DonneesImpositionTfu extends BaseEntity implements Serializable {
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
private Personne personne ; private Personne personne ;
private Boolean parcelleContact;
} }

View File

@@ -1,7 +1,8 @@
package io.gmss.fiscad.enums; package io.gmss.fiscad.enums;
public enum NatureImpot { public enum NatureImpot {
TFU, FB,
FNB,
IRF, IRF,
SRTB SRTB
} }

View File

@@ -3,7 +3,11 @@ package io.gmss.fiscad.enums;
public enum UserProfile { public enum UserProfile {
INSPECTEUR_GESTIONNAIRE, INSPECTEUR_GESTIONNAIRE,
ADMIN_FONCTIONNEL, ADMIN_FONCTIONNEL,
ADMIN_TECHNIQUE,
INSPECTEUR_GESTIONNAIRE_CHEF_SERVICE,
AGENT_CONSTATATION_ASSIETTE,
CONSULTATION,
ENQUETEUR,
INSPECTEUR_GESTIONNAIRE_CHEF_SECTEUR, INSPECTEUR_GESTIONNAIRE_CHEF_SECTEUR,
INSPECTEUR_GESTIONNAIRE_CHEF_SECTION,
INSPECTEUR_GESTIONNAIRE_CHEF_CENTRE INSPECTEUR_GESTIONNAIRE_CHEF_CENTRE
} }

View File

@@ -86,6 +86,11 @@ public class PersonneServiceImpl implements PersonneService {
return null; return null;
} }
@Override
public Page<PersonnePayLoadWeb> getPersonneListNonAssigneePage(Pageable pageable) {
return personneRepository.findAllPersonneNonAssigneCentreToDto(pageable);
}
@Override @Override
public List<PersonnePayLoadWeb> getPersonneList() { public List<PersonnePayLoadWeb> getPersonneList() {
return null; return null;

View File

@@ -0,0 +1,187 @@
package io.gmss.fiscad.implementations.rfu.metier;
import io.gmss.fiscad.entities.rfu.metier.CommuneCentreAssignation;
import io.gmss.fiscad.entities.user.User;
import io.gmss.fiscad.exceptions.BadRequestException;
import io.gmss.fiscad.exceptions.NotFoundException;
import io.gmss.fiscad.interfaces.rfu.metier.CommuneCentreAssignationService;
import io.gmss.fiscad.paylaods.request.crudweb.CommuneCentreAssignationPaylaodWeb;
import io.gmss.fiscad.persistence.repositories.decoupage.CommuneRepository;
import io.gmss.fiscad.persistence.repositories.infocad.metier.ParcelleRepository;
import io.gmss.fiscad.persistence.repositories.infocad.parametre.PersonneRepository;
import io.gmss.fiscad.persistence.repositories.infocad.parametre.StructureRepository;
import io.gmss.fiscad.persistence.repositories.rfu.metier.CommuneCentreAssignationRepository;
import io.gmss.fiscad.service.EntityFromPayLoadService;
import jakarta.ws.rs.NotAcceptableException;
import lombok.AllArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
@AllArgsConstructor
@Service
public class CommuneCentreAssignationServiceImpl implements CommuneCentreAssignationService {
private final EntityFromPayLoadService entityFromPayLoadService;
private final CommuneRepository communeRepository;
private final StructureRepository structureRepository ;
private final PersonneRepository personneRepository ;
private final ParcelleRepository parcelleRepository ;
private final CommuneCentreAssignationRepository communeCentreAssignationRepository;
@Override
public CommuneCentreAssignationPaylaodWeb createCommuneCentreAssignation(User user, CommuneCentreAssignationPaylaodWeb communeCentreAssignationPaylaodWeb) throws BadRequestException {
if (user.getStructure() == null) {
throw new BadRequestException("Impossible de créer l'assignation: Votre centre doit être précisé.");
}
if (user.getStructure().getCommune() == null) {
throw new BadRequestException("Impossible de créer un nouveau communeCentreAssignation: votre commune doit être précisée.");
}
if (communeCentreAssignationPaylaodWeb.getPersonneId() == null) {
throw new BadRequestException("Impossible de créer un nouveau communeCentreAssignation: Le contribuable doit être précisée.");
}else {
if(!personneRepository.existsById(communeCentreAssignationPaylaodWeb.getPersonneId()))
throw new BadRequestException("Impossible de créer un nouveau communeCentreAssignation: Le contribuable doit être précisée.");
}
if (communeCentreAssignationPaylaodWeb.getParcelleContactId() == null) {
throw new BadRequestException("Impossible de créer une nouvelle assignation de centre : La parcelle de contact doit être précisée.");
}else {
if(!parcelleRepository.existsById(communeCentreAssignationPaylaodWeb.getParcelleContactId()))
throw new BadRequestException("Impossible de créer une nouvelle assignation de centre: La parcelle précisée n'existe pas.");
}
Optional<CommuneCentreAssignationPaylaodWeb> communeCentreAssignationPaylaodWebOptional=communeCentreAssignationRepository.findbyCommuneAndPersonne(user.getStructure().getCommune().getId(),communeCentreAssignationPaylaodWeb.getPersonneId());
if(communeCentreAssignationPaylaodWeb.getId()==null && communeCentreAssignationPaylaodWebOptional.isPresent()){
throw new NotAcceptableException("Impossible de créer une nouvelle assignation de centre: Le contribuable est déjà assigné au centre : "+communeCentreAssignationPaylaodWebOptional.get().getStructureNom());
}
CommuneCentreAssignation communeCentreAssignation= entityFromPayLoadService.getCommuneCentreAssignationFromPayLoadWeb(communeCentreAssignationPaylaodWeb);
communeCentreAssignation.setStructure(user.getStructure());
communeCentreAssignation.setCommune(user.getStructure().getCommune());
communeCentreAssignation= communeCentreAssignationRepository.save(communeCentreAssignation);
return communeCentreAssignationRepository.findUnique(communeCentreAssignation.getId()).orElse(null);
}
@Override
public CommuneCentreAssignationPaylaodWeb updateCommuneCentreAssignation(Long id,CommuneCentreAssignationPaylaodWeb communeCentreAssignationPaylaodWeb) throws NotFoundException {
if (communeCentreAssignationPaylaodWeb.getId() == null) {
throw new BadRequestException("Impossible de modifier un nouveau communeCentreAssignation ayant un id null.");
}
if (communeCentreAssignationPaylaodWeb.getCommuneId() == null) {
throw new BadRequestException("Impossible de modifier un nouveau communeCentreAssignation: La commune doit être précisée.");
}else {
if(!communeRepository.existsById(communeCentreAssignationPaylaodWeb.getCommuneId()))
throw new BadRequestException("Impossible de modifier un nouveau communeCentreAssignation: La commune doit être précisée.");
}
if (communeCentreAssignationPaylaodWeb.getStructureId() == null) {
throw new BadRequestException("Impossible de modifier un nouveau communeCentreAssignation: Le centre doit être précisée.");
}else {
if(!structureRepository.existsById(communeCentreAssignationPaylaodWeb.getStructureId()))
throw new BadRequestException("Impossible de modifier un nouveau communeCentreAssignation: Le centre doit être précisée.");
}
if (communeCentreAssignationPaylaodWeb.getPersonneId() == null) {
throw new BadRequestException("Impossible de modifier un nouveau communeCentreAssignation: Le contribuable doit être précisée.");
}else {
if(!personneRepository.existsById(communeCentreAssignationPaylaodWeb.getPersonneId()))
throw new BadRequestException("Impossible de modifier un nouveau communeCentreAssignation: Le contribuable doit être précisée.");
}
CommuneCentreAssignation communeCentreAssignation= entityFromPayLoadService.getCommuneCentreAssignationFromPayLoadWeb(communeCentreAssignationPaylaodWeb);
communeCentreAssignation= communeCentreAssignationRepository.save(communeCentreAssignation);
return communeCentreAssignationRepository.findUnique(communeCentreAssignation.getId()).orElse(null);
}
@Override
public CommuneCentreAssignationPaylaodWeb detacherCommuneCentreAssignation(User user, CommuneCentreAssignationPaylaodWeb communeCentreAssignationPaylaodWeb) throws NotFoundException {
if (communeCentreAssignationPaylaodWeb.getId() != null) {
throw new BadRequestException("Impossible de fait de detachement. L'assignation n'est pas précisée");
}
Optional<CommuneCentreAssignation> communeCentreAssignationOptional= communeCentreAssignationRepository.findById(communeCentreAssignationPaylaodWeb.getId());
if (communeCentreAssignationOptional.isEmpty()) {
throw new BadRequestException("Impossible de fait de detachement. L'assignation n'est pas précisée");
}
if(communeCentreAssignationOptional.get().getStructure() != user.getStructure()){
throw new BadRequestException("Impossible de fait de detachement. Le contribuable n'est pas rattaché à votre centre. Veuillez contracter : "+user.getStructure().getNom());
}
communeCentreAssignationOptional.get().setStructure(null);
CommuneCentreAssignation communeCentreAssignation = communeCentreAssignationRepository.save(communeCentreAssignationOptional.get());
return communeCentreAssignationRepository.findUnique(communeCentreAssignation.getId()).orElse(null);
}
@Override
public void deleteCommuneCentreAssignation(Long id) throws NotFoundException {
Optional<CommuneCentreAssignation> communeCentreAssignationOptional = communeCentreAssignationRepository.findById(id);
if (communeCentreAssignationOptional.isPresent()) {
communeCentreAssignationRepository.deleteById(communeCentreAssignationOptional.get().getId());
} else {
throw new NotFoundException("Impossible de trouver le communeCentreAssignation spécifié dans notre base de données.");
}
}
@Override
public Page<CommuneCentreAssignationPaylaodWeb> getCommuneCentreAssignationList(Pageable pageable) {
return communeCentreAssignationRepository.findAllPayload(pageable);
}
@Override
public Page<CommuneCentreAssignationPaylaodWeb> getCommuneCentreAssignationListByCommunePageable(Long communeId, Pageable pageable) {
return communeCentreAssignationRepository.findByCommuneId(communeId,pageable);
}
@Override
public Optional<CommuneCentreAssignationPaylaodWeb> getCommuneCentreAssignationById(Long id) {
if (communeCentreAssignationRepository.existsById(id)) {
return communeCentreAssignationRepository.findUnique(id);
} else {
throw new NotFoundException("Impossible de trouver le centre d'assignation spécifiée dans la base de données.");
}
}
@Override
public Optional<CommuneCentreAssignationPaylaodWeb> getCommuneCentreAssignationByPersonneIdCommune(User user,Long personneId) {
if (user.getStructure() == null) {
throw new BadRequestException("Impossible de récuperer l'assignation: Votre centre doit être précisé.");
}
if (user.getStructure().getCommune() == null) {
throw new BadRequestException("Impossible de récuperer une assignation: votre commune doit être précisée.");
}
if (personneId == null) {
throw new BadRequestException("Impossible de récuperer l'assignation: Le contribuable doit être précisée.");
}else {
if(!personneRepository.existsById(personneId))
throw new BadRequestException("Impossible de récuperer l'assignation: Le contribuable précisée n'existe pas.");
}
Optional<CommuneCentreAssignationPaylaodWeb> communeCentreAssignationPaylaodWebOptional=communeCentreAssignationRepository.findbyCommuneAndPersonne(user.getStructure().getCommune().getId(),personneId);
return communeCentreAssignationPaylaodWebOptional;
}
@Override
public Page<CommuneCentreAssignationPaylaodWeb> getCommuneCentreAssignationListByCentrePageable(Long centreId, Pageable pageable) {
return communeCentreAssignationRepository.findByStructureId(centreId,pageable);
}
}

View File

@@ -38,6 +38,11 @@ public class DeclarationNcServiceImpl implements DeclarationNcService {
if (!structureRepository.existsById(declarationNcPayloadWeb.getStructureId())) { if (!structureRepository.existsById(declarationNcPayloadWeb.getStructureId())) {
throw new BadRequestException("Veuillez préciser le centre."); throw new BadRequestException("Veuillez préciser le centre.");
} }
List<DeclarationNcPayloadWeb> declarationNcPayloadWebs= declarationNcRepository.findAllDeclarationNcByNcNotPersonneToDto(declarationNcPayloadWeb.getNc(),declarationNcPayloadWeb.getPersonneId());
if (!declarationNcPayloadWebs.isEmpty()) {
throw new BadRequestException("Ce numéro Contribuable est déjà rattaché à un autre IFU");
}
DeclarationNc declarationNc= entityFromPayLoadService.getDeclarationNcFromPayLoadWeb(declarationNcPayloadWeb); DeclarationNc declarationNc= entityFromPayLoadService.getDeclarationNcFromPayLoadWeb(declarationNcPayloadWeb);
declarationNc =declarationNcRepository.save(declarationNc); declarationNc =declarationNcRepository.save(declarationNc);

View File

@@ -109,21 +109,66 @@ public class DonneesImpositionTfuServiceImpl implements DonneesImpositionTfuServ
return impositionsTfuRepository.findByIdToDto(impositionsTfu.getId()).orElse(null); return impositionsTfuRepository.findByIdToDto(impositionsTfu.getId()).orElse(null);
} }
@Override
@Transactional
public ImpositionsTfuPaylaodWeb genererDonneesFiscalesParcelleNonBatieUneParcelle(ImpositionsTfuPaylaodWeb impositionsTfuPaylaodWeb, Long userId,Long parcelleId) {
Integer nb= donneesImpositionTfuRepository.genererDonneesTfuNonBatie(impositionsTfuPaylaodWeb.getId(),userId,parcelleId);
ImpositionsTfu impositionsTfu = entityFromPayLoadService.getImpositionsTfuFromPayLoadWeb(impositionsTfuPaylaodWeb);
impositionsTfu.setStatusAvis(StatusAvis.TFU_FNB_GENERE);
impositionsTfu.setNombreAvisFnb(nb);
impositionsTfuRepository.save(impositionsTfu);
return impositionsTfuRepository.findByIdToDto(impositionsTfu.getId()).orElse(null);
}
@Override @Override
@Transactional @Transactional
public ImpositionsTfuPaylaodWeb genererDonneesFiscalesParcelleBatie(ImpositionsTfuPaylaodWeb impositionsTfuPaylaodWeb, Long userId) { public ImpositionsTfuPaylaodWeb genererDonneesFiscalesParcelleBatie(ImpositionsTfuPaylaodWeb impositionsTfuPaylaodWeb, Long userId) {
Integer nbb= donneesImpositionTfuRepository.genererDonneesTfuBatie(impositionsTfuPaylaodWeb.getId(),userId); Integer nbb= donneesImpositionTfuRepository.genererDonneesTfuBatie(impositionsTfuPaylaodWeb.getId(),userId);
Integer nbirfbtPlusieursBati = donneesImpositionTfuRepository.majDonneesTfuBatiePlusieursBatiment(impositionsTfuPaylaodWeb.getId());
Integer nbulo= donneesImpositionTfuRepository.genererDonneesTfuBatieUniteLogement(impositionsTfuPaylaodWeb.getId(),userId); Integer nbulo= donneesImpositionTfuRepository.genererDonneesTfuBatieUniteLogement(impositionsTfuPaylaodWeb.getId(),userId);
Integer nbirfbt= donneesImpositionTfuRepository.genererDonneesIrfBatie(impositionsTfuPaylaodWeb.getId(),userId); Integer nbirfbt= donneesImpositionTfuRepository.genererDonneesIrfBatie(impositionsTfuPaylaodWeb.getId(),userId);
//
Integer nbirfulo= donneesImpositionTfuRepository.genererDonneesIrfBatieUniteLogement(impositionsTfuPaylaodWeb.getId(),userId); Integer nbirfulo= donneesImpositionTfuRepository.genererDonneesIrfBatieUniteLogement(impositionsTfuPaylaodWeb.getId(),userId);
//
Integer nbsrtbbt= donneesImpositionTfuRepository.genererDonneesSrtbBatie(impositionsTfuPaylaodWeb.getId(),userId); Integer nbsrtbbt= donneesImpositionTfuRepository.genererDonneesSrtbBatie(impositionsTfuPaylaodWeb.getId(),userId);
//
Integer nbsrtbulo= donneesImpositionTfuRepository.genererDonneesSrtbBatieUniteLogement(impositionsTfuPaylaodWeb.getId(),userId);
ImpositionsTfu impositionsTfu = entityFromPayLoadService.getImpositionsTfuFromPayLoadWeb(impositionsTfuPaylaodWeb);
impositionsTfu.setStatusAvis(StatusAvis.GENERE);
impositionsTfu.setNombreAvis(nbb+nbulo+ (impositionsTfu.getNombreAvisFnb()==null?0:impositionsTfu.getNombreAvisFnb()));
impositionsTfu.setNombreAvisBatiment(nbb);
impositionsTfu.setNombreAvisUniteLog(nbulo);
impositionsTfuRepository.save(impositionsTfu);
return impositionsTfuRepository.findByIdToDto(impositionsTfu.getId()).orElse(null);
}
@Override
@Transactional
public ImpositionsTfuPaylaodWeb genererDonneesFiscalesParcelleBatieUneParcelle(ImpositionsTfuPaylaodWeb impositionsTfuPaylaodWeb, Long userId, Long parcelleId) {
Integer nbb= donneesImpositionTfuRepository.genererDonneesTfuBatie(impositionsTfuPaylaodWeb.getId(),userId,parcelleId);
Integer nbirfbtPlusieursBati = donneesImpositionTfuRepository.majDonneesTfuBatiePlusieursBatiment(impositionsTfuPaylaodWeb.getId(),parcelleId);
Integer nbulo= donneesImpositionTfuRepository.genererDonneesTfuBatieUniteLogement(impositionsTfuPaylaodWeb.getId(),userId,parcelleId);
Integer nbirfbt= donneesImpositionTfuRepository.genererDonneesIrfBatie(impositionsTfuPaylaodWeb.getId(),userId,parcelleId);
Integer nbirfulo= donneesImpositionTfuRepository.genererDonneesIrfBatieUniteLogement(impositionsTfuPaylaodWeb.getId(),userId,parcelleId);
Integer nbsrtbbt= donneesImpositionTfuRepository.genererDonneesSrtbBatie(impositionsTfuPaylaodWeb.getId(),userId,parcelleId);
ImpositionsTfu impositionsTfu = entityFromPayLoadService.getImpositionsTfuFromPayLoadWeb(impositionsTfuPaylaodWeb); ImpositionsTfu impositionsTfu = entityFromPayLoadService.getImpositionsTfuFromPayLoadWeb(impositionsTfuPaylaodWeb);

View File

@@ -21,6 +21,7 @@ public interface PersonneService {
void deletePersonne(Long id) throws NotFoundException; void deletePersonne(Long id) throws NotFoundException;
Page<PersonnePayLoadWeb> getPersonneList(Pageable pageable); Page<PersonnePayLoadWeb> getPersonneList(Pageable pageable);
Page<PersonnePayLoadWeb> getPersonneListNonAssigneePage(Pageable pageable);
List<PersonnePayLoadWeb> getPersonneList(); List<PersonnePayLoadWeb> getPersonneList();

View File

@@ -0,0 +1,38 @@
package io.gmss.fiscad.interfaces.rfu.metier;
import io.gmss.fiscad.entities.user.User;
import io.gmss.fiscad.exceptions.BadRequestException;
import io.gmss.fiscad.exceptions.NotFoundException;
import io.gmss.fiscad.paylaods.request.crudweb.CommuneCentreAssignationPaylaodWeb;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import java.util.List;
import java.util.Optional;
public interface CommuneCentreAssignationService {
CommuneCentreAssignationPaylaodWeb createCommuneCentreAssignation(User user, CommuneCentreAssignationPaylaodWeb communeCentreAssignationPaylaodWeb) throws BadRequestException;
CommuneCentreAssignationPaylaodWeb updateCommuneCentreAssignation(Long id,CommuneCentreAssignationPaylaodWeb communeCentreAssignationPaylaodWeb) throws NotFoundException;
CommuneCentreAssignationPaylaodWeb detacherCommuneCentreAssignation(User user,CommuneCentreAssignationPaylaodWeb communeCentreAssignationPaylaodWeb) throws NotFoundException;
void deleteCommuneCentreAssignation(Long id) throws NotFoundException;
Page<CommuneCentreAssignationPaylaodWeb> getCommuneCentreAssignationList(Pageable pageable);
Page<CommuneCentreAssignationPaylaodWeb> getCommuneCentreAssignationListByCommunePageable(Long communeId, Pageable pageable);
Optional<CommuneCentreAssignationPaylaodWeb> getCommuneCentreAssignationById(Long id);
Optional<CommuneCentreAssignationPaylaodWeb> getCommuneCentreAssignationByPersonneIdCommune(User user,Long personneId);
Page<CommuneCentreAssignationPaylaodWeb> getCommuneCentreAssignationListByCentrePageable(Long centreId, Pageable pageable);
// public CommuneCentreAssignationPaylaodWeb getCommuneCentreAssignationPersonneCommune(User user, Long personneId);
}

View File

@@ -27,6 +27,7 @@ public interface DonneesImpositionTfuService {
ImpositionsTfuPaylaodWeb genererDonneesFiscalesParcelleBatie(ImpositionsTfuPaylaodWeb impositionsTfuPaylaodWeb,Long userId); ImpositionsTfuPaylaodWeb genererDonneesFiscalesParcelleBatie(ImpositionsTfuPaylaodWeb impositionsTfuPaylaodWeb,Long userId);
ImpositionsTfuPaylaodWeb genererDonneesFiscalesParcelleNonBatie(ImpositionsTfuPaylaodWeb impositionsTfuPaylaodWeb,Long userId); ImpositionsTfuPaylaodWeb genererDonneesFiscalesParcelleNonBatie(ImpositionsTfuPaylaodWeb impositionsTfuPaylaodWeb,Long userId);
public ImpositionsTfuPaylaodWeb genererDonneesFiscalesParcelleNonBatieUneParcelle(ImpositionsTfuPaylaodWeb impositionsTfuPaylaodWeb, Long userId,Long parcelleId);
List<DonneesImpositionPaylaodWeb> getDonneesFiscalesByImposition(Long impositionsId); List<DonneesImpositionPaylaodWeb> getDonneesFiscalesByImposition(Long impositionsId);
List<DonneesImpositionTfu> getDonneesFiscalesByImpositionArrondissement(Long impositionsId,Long arrondissementId); List<DonneesImpositionTfu> getDonneesFiscalesByImpositionArrondissement(Long impositionsId,Long arrondissementId);
Page<DonneesImpositionPaylaodWeb> getDonneesFiscalesByImpositionTfuIdPageable(Long impositionsTfuId, Pageable pageable); Page<DonneesImpositionPaylaodWeb> getDonneesFiscalesByImpositionTfuIdPageable(Long impositionsTfuId, Pageable pageable);
@@ -47,5 +48,7 @@ public interface DonneesImpositionTfuService {
List<DonneesImpositionPaylaodWeb> getDonneesFiscalesByPersonneId(Long personneId); List<DonneesImpositionPaylaodWeb> getDonneesFiscalesByPersonneId(Long personneId);
public ImpositionsTfuPaylaodWeb genererDonneesFiscalesParcelleBatieUneParcelle(ImpositionsTfuPaylaodWeb impositionsTfuPaylaodWeb, Long userId, Long parcelleId);
} }

View File

@@ -0,0 +1,55 @@
package io.gmss.fiscad.paylaods.request.crudweb;
import lombok.Data;
import lombok.NoArgsConstructor;
@NoArgsConstructor
@Data
public class CommuneCentreAssignationPaylaodWeb {
private Long id;
private String code;
private String nom;
private Long communeId;
private String communeCode;
private String communeNom;
private Long structureId;
private String structureCode;
private String structureNom;
private Long personneId;
private String personneNom;
private String personnePrenom;
private String personneRaisonSociale;
private String personneIfu;
private String personneNc;
private String personneNpi;
private Long parcelleContactId;
private String parcelleContactQuartierCode;
private String parcelleContactQ;
private String parcelleContactI;
private String parcelleContactP;
private String adresseContact;
public CommuneCentreAssignationPaylaodWeb(Long id, Long communeId, String communeCode, String communeNom, Long structureId, String structureCode, String structureNom, Long personneId, String personneNom, String personnePrenom, String personneRaisonSociale, String personneIfu, String personneNc, String personneNpi, Long parcelleContactId, String parcelleContactQuartierCode, String parcelleContactQ, String parcelleContactI, String parcelleContactP,
String adresseContact) {
this.id = id;
this.communeId = communeId;
this.communeCode = communeCode;
this.communeNom = communeNom;
this.structureId = structureId;
this.structureCode = structureCode;
this.structureNom = structureNom;
this.personneId = personneId;
this.personneNom = personneNom;
this.personnePrenom = personnePrenom;
this.personneRaisonSociale = personneRaisonSociale;
this.personneIfu = personneIfu;
this.personneNc = personneNc;
this.personneNpi = personneNpi;
this.parcelleContactId = parcelleContactId;
this.parcelleContactQuartierCode = parcelleContactQuartierCode;
this.parcelleContactQ = parcelleContactQ;
this.parcelleContactI = parcelleContactI;
this.parcelleContactP = parcelleContactP;
this.adresseContact=adresseContact;
}
}

View File

@@ -15,6 +15,11 @@ public class DeclarationNcPayloadWeb {
private LocalDate dateDerniereDeclaration; private LocalDate dateDerniereDeclaration;
private LocalDate dateDeclarationNc; private LocalDate dateDeclarationNc;
private String nc; private String nc;
private String q;
private String i;
private String p;
private String numeroTitreFoncier;
private String nup;
private Long structureId; private Long structureId;
private String structureCode; private String structureCode;
private String structureNom; private String structureNom;
@@ -24,7 +29,14 @@ public class DeclarationNcPayloadWeb {
private String personneRaisonSociale; private String personneRaisonSociale;
private String observation; private String observation;
public DeclarationNcPayloadWeb(Long id, LocalDate dateDerniereDeclaration, LocalDate dateDeclarationNc, String nc, Long structureId, String structureCode, String structureNom, Long personneId, String personneNom, String personnePrenom, String personneRaisonSociale, String observation) { public DeclarationNcPayloadWeb(Long id, LocalDate dateDerniereDeclaration, LocalDate dateDeclarationNc, String nc, Long structureId, String structureCode, String structureNom, Long personneId, String personneNom, String personnePrenom, String personneRaisonSociale,
String observation,
String q,
String i,
String p,
String numeroTitreFoncier,
String nup
) {
this.id = id; this.id = id;
this.dateDerniereDeclaration = dateDerniereDeclaration; this.dateDerniereDeclaration = dateDerniereDeclaration;
this.dateDeclarationNc = dateDeclarationNc; this.dateDeclarationNc = dateDeclarationNc;
@@ -36,6 +48,11 @@ public class DeclarationNcPayloadWeb {
this.personneNom = personneNom; this.personneNom = personneNom;
this.personnePrenom = personnePrenom; this.personnePrenom = personnePrenom;
this.personneRaisonSociale = personneRaisonSociale; this.personneRaisonSociale = personneRaisonSociale;
this.q = q;
this.i = i;
this.p = p;
this.numeroTitreFoncier = numeroTitreFoncier;
this.observation = observation; this.observation = observation;
this.nup = nup;
} }
} }

View File

@@ -0,0 +1,497 @@
/*CREATE OR REPLACE FUNCTION public.generer_donnees_imposition_srtb_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_montant_srtb NUMERIC;
BEGIN
-- récupération de l'anné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;
select value
into STRICT v_montant_srtb
from parameters
where name ='TAXE_SRTB';
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% de la surperficie au sol de la parcelle
valeur_locative_adm_taux_prop_parc,
tfu_calcule_taux_prop_parc, ----tfu correspondant au 70%
valeur_locative_adm_sup_reel,
valeur_locative_adm, ----------valeur locative administrative
tfu_superficie_au_sol_reel, ----tfu correspondant à la superficie au sol reelle
tfu_piscine,
montant_taxe, ----tfu finale
taux_tfu, ----taux tfu batie
parcelle_id,
batiment_id,
unite_logement_id,
superficie_au_sol_loue
)
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,
(
CURRENT_DATE >= ep.date_debut_exemption
AND CURRENT_DATE <= COALESCE(ep.date_fin_exemption, CURRENT_DATE)
),
(
CURRENT_DATE >= eb.date_debut_excemption
AND CURRENT_DATE <= COALESCE(eb.date_fin_excemption, CURRENT_DATE)
),
cb.standing,
cb.nom,
eb.nombre_piscine,
eb.date_enquete,
st.id,
ep.zone_rfu_id,
'SRTB',
p.superficie,
eb.superficie_au_sol,
case -------valeur_batiment
WHEN eb.valeur_batiment_reel IS NOT NULL AND eb.valeur_batiment_reel <> 0 THEN eb.valeur_batiment_reel
WHEN eb.valeur_batiment_calcule IS NOT NULL AND eb.valeur_batiment_calcule <> 0 THEN eb.valeur_batiment_calcule
WHEN eb.valeur_batiment_estime IS NOT NULL AND eb.valeur_batiment_estime <> 0 THEN eb.valeur_batiment_estime
ELSE 0
END,
brb.valeur_locative,
case ----- montant_loyer_annuel
WHEN eb.montant_locatif_annuel_declare IS NOT NULL AND eb.montant_locatif_annuel_declare <> 0 THEN eb.montant_locatif_annuel_declare
WHEN eb.montant_locatif_annuel_calcule IS NOT NULL AND eb.montant_locatif_annuel_calcule <> 0 THEN eb.montant_locatif_annuel_calcule
WHEN eb.montant_locatif_annuel_estime IS NOT NULL AND eb.montant_locatif_annuel_estime <> 0 THEN eb.montant_locatif_annuel_estime
ELSE 0
END,
brb.tfu_metre_carre,
brb.tfu_minimum,
p_impositions_tfu_id,
false,
current_date ,
p_user_id ,
'FISCAD',
current_date ,
p_user_id,
eb.categorie_usage,
0,---superficie_au_sol_70pour100
0,
0,
eb.superficie_au_sol * brb.valeur_locative,
0, ------ valeur_locative_adm : en attente de update
0,
0,
v_montant_srtb,
0,
p.id,
b.id,
null,
eb.superficie_louee
FROM parcelle p
LEFT JOIN (
SELECT DISTINCT ON (parcelle_id)
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
ORDER BY parcelle_id, date_enquete DESC, id DESC
) ep ON ep.parcelle_id = p.id
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
--JOIN secteur_decoupage sd ON sd.quartier_id = q.id
JOIN (
SELECT DISTINCT ON (quartier_id)
quartier_id,
secteur_id
FROM secteur_decoupage
ORDER BY quartier_id
) sd ON sd.quartier_id = q.id
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
JOIN batiment b ON b.parcelle_id = p.id
JOIN (
SELECT DISTINCT ON (batiment_id)
batiment_id,
superficie_au_sol,
nombre_piscine,
categorie_batiment_id,
date_enquete,
montant_locatif_annuel_declare,
montant_locatif_annuel_calcule,
montant_locatif_annuel_estime,
date_debut_excemption,
date_fin_excemption,
valeur_batiment_reel,
valeur_batiment_calcule,
valeur_batiment_estime,
u.categorie_usage,
superficie_louee
FROM enquete_batiment eb
join usage u on u.id=eb.usage_id
ORDER BY batiment_id, date_enquete DESC, eb.id DESC
) eb ON eb.batiment_id = b.id
JOIN categorie_batiment cb
ON cb.id = eb.categorie_batiment_id
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 NOT EXISTS (
SELECT 1
FROM unite_logement ul
WHERE ul.batiment_id = b.id
)
AND st.id = v_structure_id
ON CONFLICT DO NOTHING;
GET DIAGNOSTICS v_rows_inserted = ROW_COUNT;
RETURN v_rows_inserted;
END;
$$; */
CREATE OR REPLACE FUNCTION public.generer_donnees_imposition_srtb_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_montant_srtb NUMERIC;
v_today DATE;
BEGIN
v_today := CURRENT_DATE;
-- 1. année + structure
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. paramètre (une seule requête)
SELECT value
INTO STRICT v_montant_srtb
FROM parameters
WHERE name = 'TAXE_SRTB';
-- 3. INSERT optimisé (SANS DISTINCT ON, SANS UPDATE)
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,
valeur_locative_adm_taux_prop_parc,
tfu_calcule_taux_prop_parc,
valeur_locative_adm_sup_reel,
valeur_locative_adm,
tfu_superficie_au_sol_reel,
tfu_piscine,
montant_taxe,
taux_tfu,
parcelle_id,
batiment_id,
unite_logement_id,
superficie_au_sol_loue,
personne_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,
(v_today BETWEEN ep.date_debut_exemption AND COALESCE(ep.date_fin_exemption, v_today)),
(v_today BETWEEN eb.date_debut_excemption AND COALESCE(eb.date_fin_excemption, v_today)),
cb.standing,
cb.nom,
COALESCE(eb.nombre_piscine, 0),
eb.date_enquete,
st.id,
ep.zone_rfu_id,
'SRTB',
p.superficie,
eb.superficie_au_sol,
-- valeur bâtiment optimisée
COALESCE(
NULLIF(eb.valeur_batiment_reel,0),
NULLIF(eb.valeur_batiment_calcule,0),
NULLIF(eb.valeur_batiment_estime,0),
0
),
brb.valeur_locative,
-- loyer optimisé
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,
0, 0, 0,
eb.superficie_au_sol * brb.valeur_locative,
0,
0,
0,
-- 🔥 SRTB = valeur directe (pas de calcul)
v_montant_srtb,
0,
p.id,
b.id,
NULL,
eb.superficie_louee,
ep.personne_id
FROM parcelle p
-- dernière enquête parcelle
LEFT JOIN LATERAL (
SELECT *
FROM enquete e
WHERE e.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
-- structure via secteur
JOIN LATERAL (
SELECT secteur_id
FROM secteur_decoupage
WHERE quartier_id = q.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
JOIN batiment b ON b.parcelle_id = p.id
-- 🔥 remplace DISTINCT ON
JOIN LATERAL (
SELECT eb2.*,u.categorie_usage
FROM enquete_batiment eb2
LEFT 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
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 NOT EXISTS (
SELECT 1
FROM unite_logement ul
WHERE ul.batiment_id = b.id
)
AND st.id = v_structure_id
ON CONFLICT DO NOTHING;
GET DIAGNOSTICS v_rows_inserted = ROW_COUNT;
RETURN v_rows_inserted;
END;
$$;

View File

@@ -0,0 +1,754 @@
/*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_valeur_locat_prof NUMERIC;
v_tfu_piscine_unitaire NUMERIC;
BEGIN
-- récupération de l'anné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;
select value
into strict v_taux_defaut_sup_sol
from parameters
where name ='TAUX_DEFAUT_SUPERFICIE_AU_SOL';
select value
into STRICT v_taux_tfu
from parameters
where name ='TAUX_TFU';
select value
into STRICT v_taux_valeur_locat_prof
from parameters
where name ='TAUX_VALEUR_LOCATIVE_PROFESSIONNELLE';
select value
into STRICT v_tfu_piscine_unitaire
from parameters
where name ='TFU_PAR_PISCINE';
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% de la surperficie au sol de la parcelle
valeur_locative_adm_taux_prop_parc,
tfu_calcule_taux_prop_parc, ----tfu correspondant au 70%
valeur_locative_adm_sup_reel,
valeur_locative_adm, ----------valeur locative administrative
tfu_superficie_au_sol_reel, ----tfu correspondant à la superficie au sol reelle
tfu_piscine,
montant_taxe, ----tfu finale
taux_tfu, ----taux tfu batie
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,
(
CURRENT_DATE >= ep.date_debut_exemption
AND CURRENT_DATE <= COALESCE(ep.date_fin_exemption, CURRENT_DATE)
),
(
CURRENT_DATE >= eb.date_debut_excemption
AND CURRENT_DATE <= COALESCE(eb.date_fin_excemption, CURRENT_DATE)
),
cb.standing,
cb.nom,
eb.nombre_piscine,
eb.date_enquete,
st.id,
ep.zone_rfu_id,
'TFU',
p.superficie,
eb.superficie_au_sol,
COALESCE(
NULLIF(eb.valeur_batiment_reel, 0),
NULLIF(eb.valeur_batiment_calcule, 0),
NULLIF(eb.valeur_batiment_estime, 0),
0
),
brb.valeur_locative,
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,
current_date ,
p_user_id ,
'FISCAD',
current_date ,
p_user_id,
eb.categorie_usage,
p.superficie*v_taux_defaut_sup_sol/100,---superficie_au_sol_70pour100
case ----valeur_locative_adm70pour100
when eb.categorie_usage = 'HABITATION' then (p.superficie * v_taux_defaut_sup_sol/100) * brb.valeur_locative
else 0
end,
case ----tfu calcule 70 pour 100 superficie parcelle
when eb.categorie_usage= 'HABITATION' then (p.superficie * v_taux_defaut_sup_sol/100) * brb.valeur_locative * v_taux_tfu/100
else 0
end,
case -----valeur_locative_adm_sup_reel
when eb.categorie_usage='HABITATION' then eb.superficie_au_sol * brb.valeur_locative
else 0
end,
0, ------ valeur_locative_adm : en attente de update
case -----tfu_superficie_au_sol_reel
when eb.categorie_usage='HABITATION' then eb.superficie_au_sol * brb.valeur_locative * v_taux_tfu/100 +eb.nombre_piscine * v_tfu_piscine_unitaire
else 0
end,
eb.nombre_piscine * v_tfu_piscine_unitaire,
0,
v_taux_tfu,
p.id,
b.id,
null
FROM parcelle p
LEFT JOIN (
SELECT DISTINCT ON (parcelle_id)
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
ORDER BY parcelle_id, date_enquete DESC, id DESC
) ep ON ep.parcelle_id = p.id
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
--JOIN secteur_decoupage sd ON sd.quartier_id = q.id
JOIN (
SELECT DISTINCT ON (quartier_id)
quartier_id,
secteur_id
FROM secteur_decoupage
ORDER BY quartier_id
) sd ON sd.quartier_id = q.id
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
JOIN batiment b ON b.parcelle_id = p.id
JOIN (
SELECT DISTINCT ON (batiment_id)
batiment_id,
superficie_au_sol,
nombre_piscine,
categorie_batiment_id,
date_enquete,
montant_locatif_annuel_declare,
montant_locatif_annuel_calcule,
montant_locatif_annuel_estime,
date_debut_excemption,
date_fin_excemption,
valeur_batiment_reel,
valeur_batiment_calcule,
valeur_batiment_estime,
u.categorie_usage
FROM enquete_batiment eb
join usage u on u.id=eb.usage_id
ORDER BY batiment_id, date_enquete DESC, eb.id DESC
) eb ON eb.batiment_id = b.id
JOIN categorie_batiment cb
ON cb.id = eb.categorie_batiment_id
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 NOT EXISTS (
SELECT 1
FROM unite_logement ul
WHERE ul.batiment_id = b.id
)
AND st.id = v_structure_id
ON CONFLICT DO NOTHING;
GET DIAGNOSTICS v_rows_inserted = ROW_COUNT;
UPDATE donnees_imposition_tfu dtfu
SET
valeur_locative_adm =
CASE
WHEN categorie_usage = 'HABITATION' AND superficie_au_sol_bat <> 0
THEN valeur_locative_adm_sup_reel
WHEN categorie_usage = 'HABITATION' AND superficie_au_sol_bat = 0
THEN valeur_locative_adm_taux_prop_parc
WHEN categorie_usage IN ('PROFESSIONNELLE','MIXTE') AND valeur_batiment <> 0
THEN valeur_batiment * (v_taux_valeur_locat_prof/100)
WHEN categorie_usage IN ('PROFESSIONNELLE','MIXTE') AND valeur_batiment = 0
THEN montant_loyer_annuel
END,
montant_taxe =
CASE
WHEN categorie_usage = 'HABITATION' AND superficie_au_sol_bat <> 0 THEN
CASE
WHEN tfu_minimum < valeur_locative_adm_sup_reel * (v_taux_tfu/100) + tfu_piscine
THEN valeur_locative_adm_sup_reel * (v_taux_tfu/100) + tfu_piscine
ELSE tfu_minimum
END
WHEN categorie_usage = 'HABITATION' AND superficie_au_sol_bat = 0 THEN
CASE
WHEN tfu_minimum < valeur_locative_adm_taux_prop_parc * (v_taux_tfu/100) + tfu_piscine
THEN valeur_locative_adm_taux_prop_parc * (v_taux_tfu/100) + tfu_piscine
ELSE tfu_minimum
END
WHEN categorie_usage IN ('PROFESSIONNELLE','MIXTE') AND valeur_batiment <> 0 THEN
CASE
WHEN tfu_minimum < valeur_batiment * (v_taux_valeur_locat_prof/100) * (v_taux_tfu/100)
THEN valeur_batiment * (v_taux_valeur_locat_prof/100) * (v_taux_tfu/100)
ELSE tfu_minimum
END
WHEN categorie_usage IN ('PROFESSIONNELLE','MIXTE') AND valeur_batiment = 0 THEN
CASE
WHEN tfu_minimum < montant_loyer_annuel * (v_taux_tfu/100)
THEN montant_loyer_annuel * (v_taux_tfu/100)
ELSE tfu_minimum
END
END
WHERE impositions_tfu_id = p_impositions_tfu_id
AND batie = TRUE
AND NOT EXISTS (
SELECT 1
FROM unite_logement ul
WHERE ul.batiment_id = dtfu.batiment_id
);
RETURN v_rows_inserted;
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,
personne_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 * eb.nombre_piscine * v_tfu_piscine_unitaire
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,
ep.personne_id
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;
$$;

View File

@@ -0,0 +1,855 @@
/*CREATE OR REPLACE FUNCTION public.generer_donnees_imposition_tfu_batie_unite_logement(
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_valeur_locat_prof NUMERIC;
v_tfu_piscine_unitaire NUMERIC;
BEGIN
-- récupération de l'anné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;
select value
into strict v_taux_defaut_sup_sol
from parameters
where name ='TAUX_DEFAUT_SUPERFICIE_AU_SOL';
select value
into STRICT v_taux_tfu
from parameters
where name ='TAUX_TFU';
RAISE NOTICE 'v_taux_tfu = %', v_taux_tfu;
select value
into STRICT v_taux_valeur_locat_prof
from parameters
where name ='TAUX_VALEUR_LOCATIVE_PROFESSIONNELLE';
select value
into STRICT v_tfu_piscine_unitaire
from parameters
where name ='TFU_PAR_PISCINE';
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,
num_unite_logement,
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,
unite_logement_exonere,
standing_bat,
categorie_bat,
nombre_piscine,
date_enquete,
structure_id,
zone_rfu_id,
nature_impot,
superficie_parc,
superficie_au_sol_bat,
superficie_au_sol_ulog,
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% de la surperficie au sol de la parcelle
valeur_locative_adm_taux_prop_parc,
tfu_calcule_taux_prop_parc, ----tfu correspondant au 70%
valeur_locative_adm_sup_reel,
valeur_locative_adm, ----------valeur locative administrative
tfu_superficie_au_sol_reel, ----tfu correspondant à la superficie au sol reelle
tfu_piscine,
montant_taxe, ----tfu finale
taux_tfu, ----taux tfu batie
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,
ul.nul,
eul.ifu,
eul.npi,
eul.tel1,
eul.email,
eul.nom,
eul.prenom,
eul.raison_sociale,
eul.adresse,
eul.representant_tel,
eul.representant_nom,
eul.representant_prenom,
p.longitude,
p.latitude,
TRUE,
(
CURRENT_DATE >= ep.date_debut_exemption
AND CURRENT_DATE <= COALESCE(ep.date_fin_exemption, CURRENT_DATE)
),
(
CURRENT_DATE >= eb.date_debut_excemption
AND CURRENT_DATE <= COALESCE(eb.date_fin_excemption, CURRENT_DATE)
),
(
CURRENT_DATE >= eul.date_debut_exemption
AND CURRENT_DATE <= COALESCE(eul.date_fin_exemption, CURRENT_DATE)
),
cb.standing,
cb.nom,
CASE
WHEN eul.nombre_piscine is null then 0
else eul.nombre_piscine
END,
eul.date_enquete,
st.id,
ep.zone_rfu_id,
'TFU',
p.superficie,
eb.superficie_au_sol,
eul.superficie_au_sol,
CASE -------valeur_batiment
WHEN eul.valeur_unite_logement_reel IS NOT NULL AND eul.valeur_unite_logement_reel <> 0 THEN eul.valeur_unite_logement_reel
WHEN eul.valeur_unite_logement_calcule IS NOT NULL AND eul.valeur_unite_logement_calcule <> 0 THEN eul.valeur_unite_logement_calcule
WHEN eul.valeur_unite_logement_estime IS NOT NULL AND eul.valeur_unite_logement_estime <> 0 THEN eul.valeur_unite_logement_estime
ELSE 0
END,
brb.valeur_locative,
CASE ----- montant_loyer_annuel
WHEN eul.montant_locatif_annuel_declare IS NOT NULL AND eul.montant_locatif_annuel_declare <> 0 THEN eul.montant_locatif_annuel_declare
WHEN eul.montant_locatif_annuel_calcule IS NOT NULL AND eul.montant_locatif_annuel_calcule <> 0 THEN eul.montant_locatif_annuel_calcule
WHEN eul.montant_locatif_annuel_estime IS NOT NULL AND eul.montant_locatif_annuel_estime <> 0 THEN eul.montant_locatif_annuel_estime
ELSE 0
END,
brb.tfu_metre_carre,
brb.tfu_minimum,
p_impositions_tfu_id,
false,
current_date,
p_user_id,
'FISCAD',
current_date,
p_user_id,
eul.categorie_usage,
p.superficie * v_taux_defaut_sup_sol/100,---superficie_au_sol_70pour100
case ----valeur_locative_adm70pour100
when eul.categorie_usage = 'HABITATION' then (p.superficie * v_taux_defaut_sup_sol/100) * brb.valeur_locative
else 0
end,
case ----tfu calcule 70 pour 100 superficie parcelle
when eul.categorie_usage= 'HABITATION' then (p.superficie * v_taux_defaut_sup_sol/100) * brb.valeur_locative * v_taux_tfu/100
else 0
end,
case -----valeur_locative_adm_sup_reel
when eul.categorie_usage='HABITATION' then eul.superficie_au_sol * brb.valeur_locative
else 0
end,
0, ------ valeur_locative_adm : en attente de update
case -----tfu_superficie_au_sol_reel
when eul.categorie_usage='HABITATION' then eul.superficie_au_sol * brb.valeur_locative * 6/100
else 0
end,
CASE
WHEN eul.nombre_piscine is null then 0
else eul.nombre_piscine * v_tfu_piscine_unitaire
END,
0,
v_taux_tfu,
p.id,
b.id,
ul.id
FROM parcelle p
LEFT JOIN (
SELECT DISTINCT ON (parcelle_id)
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
ORDER BY parcelle_id, date_enquete DESC, id DESC
) ep ON ep.parcelle_id = p.id
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
--JOIN secteur_decoupage sd ON sd.quartier_id = q.id
JOIN (
SELECT DISTINCT ON (quartier_id)
quartier_id,
secteur_id
FROM secteur_decoupage
ORDER BY quartier_id
) sd ON sd.quartier_id = q.id
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
JOIN batiment b ON b.parcelle_id = p.id
JOIN (
SELECT DISTINCT ON (batiment_id)
batiment_id,
superficie_au_sol,
nombre_piscine,
categorie_batiment_id,
date_enquete,
montant_locatif_annuel_declare,
montant_locatif_annuel_calcule,
montant_locatif_annuel_estime,
date_debut_excemption,
date_fin_excemption,
valeur_batiment_reel,
valeur_batiment_calcule,
valeur_batiment_estime,
u.categorie_usage
FROM enquete_batiment eb
join usage u on u.id=eb.usage_id
ORDER BY batiment_id, date_enquete DESC, eb.id DESC
) eb ON eb.batiment_id = b.id
JOIN unite_logement ul on ul.batiment_id = b.id
JOIN (
SELECT DISTINCT ON (eult.unite_logement_id)
eult.unite_logement_id,
pers1.id,
pers1.ifu,
pers1.npi,
pers1.tel1,
pers1.email,
pers1.nom,
pers1.prenom,
pers1.raison_sociale,
pers1.adresse,
eult.nombre_piscine,
eult.categorie_batiment_id,
eult.superficie_au_sol,
eult.superficie_louee,
eult.nbre_piece,
eult.date_enquete,
eult.montant_locatif_annuel_calcule,
eult.montant_locatif_annuel_declare,
eult.montant_locatif_annuel_estime,
eult.date_debut_exemption,
eult.date_fin_exemption,
eult.representant_nom,
eult.representant_prenom,
eult.representant_tel,
eult.valeur_unite_logement_reel,
eult.valeur_unite_logement_calcule,
eult.valeur_unite_logement_estime,
u.categorie_usage
FROM enquete_unite_logement eult
join usage u on u.id=eult.usage_id
left join personne pers1 on pers1.id = eult.personne_id
ORDER BY unite_logement_id, date_enquete DESC, eult.id DESC
) eul ON eul.unite_logement_id = ul.id
JOIN categorie_batiment cb
ON cb.id = eul.categorie_batiment_id
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 EXISTS (
SELECT 1
FROM unite_logement ul
WHERE ul.batiment_id = b.id
)
AND st.id = v_structure_id
ON CONFLICT DO NOTHING;
GET DIAGNOSTICS v_rows_inserted = ROW_COUNT;
UPDATE donnees_imposition_tfu dtfu
SET
valeur_locative_adm =
CASE
WHEN categorie_usage = 'HABITATION' AND superficie_au_sol_ulog <> 0
THEN valeur_locative_adm_sup_reel
WHEN categorie_usage = 'HABITATION' AND superficie_au_sol_ulog = 0
THEN valeur_locative_adm_taux_prop_parc
WHEN categorie_usage IN ('PROFESSIONNELLE','MIXTE') AND valeur_batiment <> 0
THEN valeur_batiment * (v_taux_valeur_locat_prof/100)
WHEN categorie_usage IN ('PROFESSIONNELLE','MIXTE') AND valeur_batiment = 0
THEN montant_loyer_annuel
END,
montant_taxe =
CASE
WHEN categorie_usage = 'HABITATION' AND superficie_au_sol_ulog <> 0 THEN
CASE
WHEN tfu_minimum < valeur_locative_adm_sup_reel * (v_taux_tfu/100) + tfu_piscine
THEN valeur_locative_adm_sup_reel * (v_taux_tfu/100) + tfu_piscine
ELSE tfu_minimum
END
WHEN categorie_usage = 'HABITATION' AND superficie_au_sol_ulog = 0 THEN
CASE
WHEN tfu_minimum < valeur_locative_adm_taux_prop_parc * (v_taux_tfu/100) + tfu_piscine
THEN valeur_locative_adm_taux_prop_parc * (v_taux_tfu/100) + tfu_piscine
ELSE tfu_minimum
END
WHEN categorie_usage IN ('PROFESSIONNELLE','MIXTE') AND valeur_batiment <> 0 THEN
CASE
WHEN tfu_minimum < valeur_batiment * (v_taux_valeur_locat_prof/100) * (v_taux_tfu/100)
THEN valeur_batiment * (v_taux_valeur_locat_prof/100) * (v_taux_tfu/100)
ELSE tfu_minimum
END
WHEN categorie_usage IN ('PROFESSIONNELLE','MIXTE') AND valeur_batiment = 0 THEN
CASE
WHEN tfu_minimum < montant_loyer_annuel * (v_taux_tfu/100)
THEN montant_loyer_annuel * (v_taux_tfu/100)
ELSE tfu_minimum
END
END
WHERE impositions_tfu_id = p_impositions_tfu_id
AND batie = TRUE
AND EXISTS (
SELECT 1
FROM unite_logement ul
WHERE ul.batiment_id = dtfu.batiment_id
);
RETURN v_rows_inserted;
END;
$$;*/
CREATE OR REPLACE FUNCTION public.generer_donnees_imposition_tfu_batie_unite_logement(
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,
num_unite_logement,
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,
unite_logement_exonere,
standing_bat,
categorie_bat,
nombre_piscine,
date_enquete,
structure_id,
zone_rfu_id,
nature_impot,
superficie_parc,
superficie_au_sol_bat,
superficie_au_sol_ulog,
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,
ul.nul,
eul.ifu,
eul.npi,
eul.tel1,
eul.email,
eul.nom,
eul.prenom,
eul.raison_sociale,
eul.adresse,
eul.representant_tel,
eul.representant_nom,
eul.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)),
-- exonere unite logement
(v_today BETWEEN eul.date_debut_exemption
AND COALESCE(eul.date_fin_exemption, v_today)),
cb.standing,
cb.nom,
COALESCE(eul.nombre_piscine, 0),
eul.date_enquete,
st.id,
ep.zone_rfu_id,
'TFU',
p.superficie,
eb.superficie_au_sol,
eul.superficie_au_sol,
-- valeur_batiment (unité logement) : première valeur non nulle non zéro
COALESCE(
NULLIF(eul.valeur_unite_logement_reel, 0),
NULLIF(eul.valeur_unite_logement_calcule, 0),
NULLIF(eul.valeur_unite_logement_estime, 0),
0
),
brb.valeur_locative,
-- montant_loyer_annuel
COALESCE(
NULLIF(eul.montant_locatif_annuel_declare, 0),
NULLIF(eul.montant_locatif_annuel_calcule, 0),
NULLIF(eul.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,
eul.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 eul.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 eul.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 eul.categorie_usage = 'HABITATION'
THEN eul.superficie_au_sol * brb.valeur_locative
ELSE 0
END,
-- ---------------------------------------------------------------
-- valeur_locative_adm avec tests explicites (corrigée)
-- ---------------------------------------------------------------
CASE
WHEN eul.categorie_usage = 'HABITATION'
AND eul.superficie_au_sol <> 0
THEN eul.superficie_au_sol * brb.valeur_locative
WHEN eul.categorie_usage = 'HABITATION'
AND eul.superficie_au_sol = 0
THEN (p.superficie * v_taux_defaut_sup_sol / 100.0) * brb.valeur_locative
-- ✅ Test explicite : valeur_unite_logement <> 0
WHEN eul.categorie_usage IN ('PROFESSIONNELLE', 'MIXTE')
AND COALESCE(NULLIF(eul.valeur_unite_logement_reel, 0),
NULLIF(eul.valeur_unite_logement_calcule, 0),
NULLIF(eul.valeur_unite_logement_estime, 0), 0) <> 0
THEN COALESCE(NULLIF(eul.valeur_unite_logement_reel, 0),
NULLIF(eul.valeur_unite_logement_calcule, 0),
NULLIF(eul.valeur_unite_logement_estime, 0), 0)
* v_taux_vlp_ratio
-- ✅ Test explicite : valeur_unite_logement = 0
WHEN eul.categorie_usage IN ('PROFESSIONNELLE', 'MIXTE')
AND COALESCE(NULLIF(eul.valeur_unite_logement_reel, 0),
NULLIF(eul.valeur_unite_logement_calcule, 0),
NULLIF(eul.valeur_unite_logement_estime, 0), 0) = 0
THEN COALESCE(NULLIF(eul.montant_locatif_annuel_declare, 0),
NULLIF(eul.montant_locatif_annuel_calcule, 0),
NULLIF(eul.montant_locatif_annuel_estime, 0), 0)
ELSE 0
END,
-- 🔧 CORRECTION : tfu_superficie_au_sol_reel (était hardcodé à 6/100)
CASE WHEN eul.categorie_usage = 'HABITATION'
THEN eul.superficie_au_sol * brb.valeur_locative * v_taux_tfu_ratio
ELSE 0
END,
-- tfu_piscine
COALESCE(eul.nombre_piscine, 0) * v_tfu_piscine_unitaire,
-- ---------------------------------------------------------------
-- montant_taxe ← calculé directement (plus d'UPDATE)
-- ---------------------------------------------------------------
(
WITH calc AS (
SELECT
COALESCE(NULLIF(eul.valeur_unite_logement_reel, 0),
NULLIF(eul.valeur_unite_logement_calcule, 0),
NULLIF(eul.valeur_unite_logement_estime, 0), 0) AS valeur_ul,
COALESCE(NULLIF(eul.montant_locatif_annuel_declare, 0),
NULLIF(eul.montant_locatif_annuel_calcule, 0),
NULLIF(eul.montant_locatif_annuel_estime, 0), 0) AS loyer,
eul.superficie_au_sol * brb.valeur_locative AS vla_reel,
(p.superficie * v_taux_defaut_sup_sol / 100.0)
* brb.valeur_locative AS vla_70,
COALESCE(eul.nombre_piscine, 0) * v_tfu_piscine_unitaire AS piscine_montant
)
SELECT
CASE
WHEN eul.categorie_usage = 'HABITATION'
AND eul.superficie_au_sol <> 0
THEN GREATEST(brb.tfu_minimum,
calc.vla_reel * v_taux_tfu_ratio
+ calc.piscine_montant)
WHEN eul.categorie_usage = 'HABITATION'
AND eul.superficie_au_sol = 0
THEN GREATEST(brb.tfu_minimum,
calc.vla_70 * v_taux_tfu_ratio
+ calc.piscine_montant)
WHEN eul.categorie_usage IN ('PROFESSIONNELLE', 'MIXTE')
AND calc.valeur_ul <> 0
THEN GREATEST(brb.tfu_minimum,
calc.valeur_ul * v_taux_vlp_ratio * v_taux_tfu_ratio)
WHEN eul.categorie_usage IN ('PROFESSIONNELLE', 'MIXTE')
AND calc.valeur_ul = 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,
ul.id
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
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
JOIN batiment b ON b.parcelle_id = p.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 unite_logement ul ON ul.batiment_id = b.id
-- Dernière enquête unité logement
JOIN LATERAL (
SELECT
eul2.unite_logement_id,
pers1.id,
pers1.ifu,
pers1.npi,
pers1.tel1,
pers1.email,
pers1.nom,
pers1.prenom,
pers1.raison_sociale,
pers1.adresse,
eul2.nombre_piscine,
eul2.categorie_batiment_id,
eul2.superficie_au_sol,
eul2.superficie_louee,
eul2.nbre_piece,
eul2.date_enquete,
eul2.montant_locatif_annuel_calcule,
eul2.montant_locatif_annuel_declare,
eul2.montant_locatif_annuel_estime,
eul2.date_debut_exemption,
eul2.date_fin_exemption,
eul2.representant_nom,
eul2.representant_prenom,
eul2.representant_tel,
eul2.valeur_unite_logement_reel,
eul2.valeur_unite_logement_calcule,
eul2.valeur_unite_logement_estime,
u.categorie_usage
FROM enquete_unite_logement eul2
JOIN usage u ON u.id = eul2.usage_id
LEFT JOIN personne pers1 ON pers1.id = eul2.personne_id
WHERE eul2.unite_logement_id = ul.id
ORDER BY eul2.date_enquete DESC, eul2.id DESC
LIMIT 1
) eul ON TRUE
JOIN categorie_batiment cb ON cb.id = eul.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 EXISTS (
SELECT 1
FROM unite_logement ul2
WHERE ul2.batiment_id = b.id
)
AND st.id = v_structure_id
ON CONFLICT DO NOTHING;
GET DIAGNOSTICS v_rows_inserted = ROW_COUNT;
RETURN v_rows_inserted;
END;
$$;

View File

@@ -0,0 +1,34 @@
-- Tables E_AVIS et E_AVIS_DETAIL
CREATE TABLE e_avis (
id_avis BIGINT NOT NULL,
r_avis VARCHAR(50),
exercice BIGINT,
r_commune VARCHAR(50),
r_centre_impot VARCHAR(50),
id_contribuable_foncier BIGINT,
ifu VARCHAR(50),
npi VARCHAR(20),
nc VARCHAR(20),
raison_social VARCHAR(500),
nom VARCHAR(500),
prenom VARCHAR(500),
date_liquidation DATE,
date_information DATE
);
CREATE TABLE e_avis_detail (
id_avis_detail BIGINT NOT NULL,
id_avis BIGINT NOT NULL,
id_impot_nature VARCHAR(50),
id_unite_foncier BIGINT NOT NULL,
nup VARCHAR(20),
r_quartier VARCHAR(50),
qip_quartier VARCHAR(10),
qip_parcelle VARCHAR(10),
batiment VARCHAR(10),
unite_logement VARCHAR(10),
montant_base_imposition NUMERIC(22,3),
montant_valeur_locative NUMERIC(22,3),
taux NUMERIC(22,10),
montant_du NUMERIC(22,3)
);

View File

@@ -0,0 +1,136 @@
-----------------
create or replace view e_avis_view as
WITH first_parcelle_imposition AS (
SELECT DISTINCT ON (personne_id)
personne_id,
parcelle_id
FROM donnees_imposition_tfu
ORDER BY personne_id, annee,parcelle_id
),
cca_unique AS (
SELECT DISTINCT ON (cc.commune_id, cc.personne_id)
cc.structure_id,
cc.personne_id,
cc.commune_id,
COALESCE(qu.code, qu_imp.code) AS r_quartier_contact,
COALESCE(parc.q, parc_imp.q) AS q_contact,
COALESCE(parc.i, parc_imp.i) AS i_contact,
COALESCE(parc.p, parc_imp.p) AS p_contact
FROM commune_centre_assignation cc
LEFT JOIN parcelle parc
ON parc.id = cc.parcelle_id
LEFT JOIN quartier qu
ON qu.id = parc.quartier_id
LEFT JOIN first_parcelle_imposition dpi
ON dpi.personne_id = cc.personne_id
LEFT JOIN parcelle parc_imp
ON parc_imp.id = dpi.parcelle_id
LEFT JOIN quartier qu_imp
ON qu_imp.id = parc_imp.quartier_id
ORDER BY cc.commune_id, cc.personne_id, cc.structure_id
)
SELECT distinct
null as id_avis,
concat(c.code,'-',dimp.ifu,'-',exo.annee) as r_avis,
exo.annee as exercice,
c.code as r_commune,
st.code as r_centre_impot,
dimp.personne_id as id_contribuable_foncier,
dimp.ifu as ifu,
dimp.npi as npi,
dimp.ifu as nc,
dimp.raison_sociale as raison_sociale,
dimp.nom_prop as nom ,
dimp.prenom_prop as prenom,
imp.date_generation as date_liquidation,
current_date as date_information,
cca.r_quartier_contact,
cca.q_contact,
cca.i_contact,
cca.p_contact
FROM impositions_tfu imp
INNER JOIN donnees_imposition_tfu dimp
ON dimp.impositions_tfu_id = imp.id
LEFT JOIN exercice exo
ON exo.id = imp.exercice_id
LEFT JOIN commune c
ON c.id = imp.commune_id
LEFT JOIN cca_unique cca
ON cca.personne_id = dimp.personne_id
AND cca.commune_id = imp.commune_id
LEFT JOIN structure st
ON st.id = cca.structure_id
order by c.code,st.code,r_quartier_contact,i_contact,p_contact;
--left join structure st2 on st2.id=imp.structure_id; 8263
create or replace view e_avis_detail_view as
WITH cca_unique AS (
SELECT DISTINCT ON (personne_id, commune_id)
structure_id,
personne_id,
commune_id,
parcelle_id
FROM commune_centre_assignation
ORDER BY commune_id,personne_id,structure_id
)
SELECT distinct on (exo.annee,dimp.parcelle_id,dimp.nature_impot)
null as id_avis_detail,
null as id_avis,
dimp.id as id_externe_ligne_imposition,
concat(c.code,'-',dimp.ifu,'-',exo.annee) as r_avis,
dimp.nature_impot as id_impot_nature,
dimp.parcelle_id as id_unite_foncier,
dimp.nup as nup,
dimp.code_quartier_village as r_quartier,
dimp.q as qip_quartier,
dimp.ilot as qip_ilot,
dimp.parcelle as qip_parcelle,
dimp.num_batiment as batiment,
dimp.num_unite_logement as unite_logement,
case
when dimp.batie = false then dimp.valeur_admin_parcelle_nb
else dimp.valeur_locative_adm
end as montant_base_imposition,
dimp.valeur_locative_adm as montant_valeur_locative,
dimp.taux_tfu as taux,
dimp.montant_taxe as montant_du,
case
when cca.parcelle_id is not null then true
else false
end as booleen_parcelle_contact
FROM impositions_tfu imp
INNER JOIN donnees_imposition_tfu dimp
ON dimp.impositions_tfu_id = imp.id
LEFT JOIN exercice exo
ON exo.id = imp.exercice_id
LEFT JOIN commune c
ON c.id = imp.commune_id
LEFT JOIN cca_unique cca
ON cca.personne_id = dimp.personne_id
AND cca.commune_id = imp.commune_id
AND cca.parcelle_id = dimp.parcelle_id
LEFT JOIN structure st
ON st.id = cca.structure_id
where dimp.personne_id is not null ;
---------------------------------------------------
select * from e_avis_detail_view
where qip_quartier='6431' and qip_ilot='1656' and qip_parcelle='C' ;
'6431', '1656', 'C'

View File

@@ -0,0 +1,5 @@
-----------------
create or replace view parcelle_view as
select distinct q.code as r_quartier,q.nom,p.nup, p.q,p.i,p.p from parcelle p
inner join quartier q on q.id=p.quartier_id

View File

@@ -597,7 +597,7 @@ BEGIN
JOIN usage u ON u.id = eb2.usage_id JOIN usage u ON u.id = eb2.usage_id
WHERE eb2.batiment_id = b.id WHERE eb2.batiment_id = b.id
-- 🔧 IRF : Filtre spécifique -- 🔧 IRF : Filtre spécifique
AND eb2.superficie_louee * eb2.montant_locatif_annuel_declare > 0 AND eb2.superficie_louee * eb2.montant_locatif_annuel_declare > 0 ---s'assurer que la superficie au sol loue est renseignée
ORDER BY eb2.date_enquete DESC, eb2.id DESC ORDER BY eb2.date_enquete DESC, eb2.id DESC
LIMIT 1 LIMIT 1
) eb ON TRUE ) eb ON TRUE

View File

@@ -0,0 +1,350 @@
CREATE OR REPLACE FUNCTION public.generer_donnees_imposition_irf_batie_une_parcelle(
p_impositions_tfu_id BIGINT,
p_user_id BIGINT,
p_parcelle_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_valeur_locat_prof NUMERIC;
v_tfu_piscine_unitaire NUMERIC;
v_taux_irf NUMERIC;
v_taux_irf_ratio NUMERIC; -- v_taux_irf / 100 (pré-calculé)
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_VALEUR_LOCATIVE_PROFESSIONNELLE'),
MAX(value) FILTER (WHERE name = 'TFU_PAR_PISCINE'),
MAX(value) FILTER (WHERE name = 'TAUX_IRF')
INTO STRICT
v_taux_defaut_sup_sol,
v_taux_valeur_locat_prof,
v_tfu_piscine_unitaire,
v_taux_irf
FROM parameters
WHERE name IN (
'TAUX_DEFAUT_SUPERFICIE_AU_SOL',
'TAUX_VALEUR_LOCATIVE_PROFESSIONNELLE',
'TFU_PAR_PISCINE',
'TAUX_IRF'
);
-- Ratio pré-calculé pour éviter la division répétée dans le SELECT
v_taux_irf_ratio := v_taux_irf / 100.0;
-- -------------------------------------------------------------------------
-- 3. INSERT avec calcul direct 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, -- 0 pour IRF
valeur_locative_adm_sup_reel,
valeur_locative_adm, -- = montant_loyer_annuel pour IRF
tfu_superficie_au_sol_reel, -- 0 pour IRF
tfu_piscine, -- 0 pour IRF
montant_taxe, -- IRF finale = loyer * taux_irf
taux_tfu, -- = taux_irf pour IRF
parcelle_id,
batiment_id,
unite_logement_id,
superficie_au_sol_loue,
personne_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,
'IRF',
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
),
-- 🔧 IRF : champs TFU mis à 0
0, -- tfu_metre_carre
0, -- 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
(p.superficie * v_taux_defaut_sup_sol / 100.0) * brb.valeur_locative,
-- 🔧 IRF : tfu_calcule_taux_prop_parc → 0
0,
-- valeur_locative_adm_sup_reel
eb.superficie_au_sol * brb.valeur_locative,
-- ---------------------------------------------------------------
-- 🔧 IRF : valeur_locative_adm = montant_loyer_annuel (calculé directement)
-- ---------------------------------------------------------------
COALESCE(
NULLIF(eb.montant_locatif_annuel_declare, 0),
NULLIF(eb.montant_locatif_annuel_calcule, 0),
NULLIF(eb.montant_locatif_annuel_estime, 0),
0
),
-- 🔧 IRF : tfu_superficie_au_sol_reel → 0
0,
-- 🔧 IRF : tfu_piscine → 0
0,
-- ---------------------------------------------------------------
-- 🔧 IRF : montant_taxe = montant_loyer_annuel * taux_irf (calculé directement)
-- ---------------------------------------------------------------
COALESCE(
NULLIF(eb.montant_locatif_annuel_declare, 0),
NULLIF(eb.montant_locatif_annuel_calcule, 0),
NULLIF(eb.montant_locatif_annuel_estime, 0),
0
) * v_taux_irf_ratio,
-- 🔧 IRF : taux_tfu → taux_irf
v_taux_irf,
p.id,
b.id,
NULL,
eb.superficie_louee,
ep.personne_id
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
-- 🔧 IRF : Dernière enquête bâtiment avec filtre spécifique IRF
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,
eb2.superficie_louee
FROM enquete_batiment eb2
JOIN usage u ON u.id = eb2.usage_id
WHERE eb2.batiment_id = b.id
-- 🔧 IRF : Filtre spécifique
AND eb2.superficie_louee * eb2.montant_locatif_annuel_declare > 0 ---s'assurer que la superficie au sol loue est renseignée
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
AND p.id=p_parcelle_id
AND NOT EXISTS(select 1 from donnees_imposition_tfu dimptfu
where dimptfu.parcelle_id=p_parcelle_id
AND dimptfu.annee=v_annee
AND dimptfu.nature_impot='IRF'
AND dimptfu.batiment_id=b.id)
ON CONFLICT DO NOTHING;
GET DIAGNOSTICS v_rows_inserted = ROW_COUNT;
RETURN v_rows_inserted;
END;
$$;

View File

@@ -0,0 +1,305 @@
CREATE OR REPLACE FUNCTION public.generer_donnees_imposition_irf_batie_ulo_une_parcelle(
p_impositions_tfu_id BIGINT,
p_user_id BIGINT,
p_parcelle_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_irf NUMERIC;
v_taux_irf_ratio NUMERIC;
v_today DATE;
BEGIN
v_today := CURRENT_DATE;
-- 1. année + structure
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. paramètres (UNE seule requête)
SELECT
MAX(value) FILTER (WHERE name = 'TAUX_DEFAUT_SUPERFICIE_AU_SOL'),
MAX(value) FILTER (WHERE name = 'TAUX_IRF')
INTO STRICT
v_taux_defaut_sup_sol,
v_taux_irf
FROM parameters
WHERE name IN (
'TAUX_DEFAUT_SUPERFICIE_AU_SOL',
'TAUX_IRF'
);
v_taux_irf_ratio := v_taux_irf / 100.0;
-- 3. INSERT optimisé
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,
num_unite_logement,
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, unite_logement_exonere,
standing_bat, categorie_bat,
nombre_piscine,
date_enquete,
structure_id,
zone_rfu_id,
nature_impot,
superficie_parc,
superficie_au_sol_bat,
superficie_au_sol_ulog,
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,
valeur_locative_adm_taux_prop_parc,
tfu_calcule_taux_prop_parc,
valeur_locative_adm_sup_reel,
valeur_locative_adm,
tfu_superficie_au_sol_reel,
tfu_piscine,
montant_taxe,
taux_tfu,
parcelle_id,
batiment_id,
unite_logement_id,
superficie_au_sol_loue,
personne_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, ul.nul,
eul.ifu, eul.npi, eul.tel1, eul.email,
eul.nom, eul.prenom, eul.raison_sociale, eul.adresse,
eul.representant_tel, eul.representant_nom, eul.representant_prenom,
p.longitude, p.latitude,
TRUE,
(v_today BETWEEN ep.date_debut_exemption AND COALESCE(ep.date_fin_exemption, v_today)),
(v_today BETWEEN eb.date_debut_excemption AND COALESCE(eb.date_fin_excemption, v_today)),
(v_today BETWEEN eul.date_debut_exemption AND COALESCE(eul.date_fin_exemption, v_today)),
cb.standing,
cb.nom,
COALESCE(eul.nombre_piscine, 0),
eul.date_enquete,
st.id,
ep.zone_rfu_id,
'IRF',
p.superficie,
eb.superficie_au_sol,
eul.superficie_au_sol,
-- valeur logement
COALESCE(
NULLIF(eul.valeur_unite_logement_reel,0),
NULLIF(eul.valeur_unite_logement_calcule,0),
NULLIF(eul.valeur_unite_logement_estime,0),
0
),
brb.valeur_locative,
-- loyer
COALESCE(
NULLIF(eul.montant_locatif_annuel_declare,0),
NULLIF(eul.montant_locatif_annuel_calcule,0),
NULLIF(eul.montant_locatif_annuel_estime,0),
0
),
0, 0,
p_impositions_tfu_id,
FALSE,
v_today, p_user_id, 'FISCAD',
v_today, p_user_id,
eul.categorie_usage,
p.superficie * v_taux_defaut_sup_sol / 100.0,
(p.superficie * v_taux_defaut_sup_sol / 100.0) * brb.valeur_locative,
0,
eul.superficie_au_sol * brb.valeur_locative,
-- valeur locative = loyer
COALESCE(
NULLIF(eul.montant_locatif_annuel_declare,0),
NULLIF(eul.montant_locatif_annuel_calcule,0),
NULLIF(eul.montant_locatif_annuel_estime,0),
0
),
0, 0,
-- montant taxe direct (PLUS D'UPDATE)
COALESCE(
NULLIF(eul.montant_locatif_annuel_declare,0),
NULLIF(eul.montant_locatif_annuel_calcule,0),
NULLIF(eul.montant_locatif_annuel_estime,0),
0
) * v_taux_irf_ratio,
v_taux_irf,
p.id,
b.id,
ul.id,
eul.superficie_louee,
eul.personne_id
FROM parcelle p
LEFT JOIN LATERAL (
SELECT *
FROM enquete e
WHERE e.parcelle_id = p.id
ORDER BY date_enquete DESC, id DESC
LIMIT 1
) ep ON TRUE
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
JOIN LATERAL (
SELECT secteur_id
FROM secteur_decoupage
WHERE quartier_id = q.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
JOIN batiment b ON b.parcelle_id = p.id
JOIN unite_logement ul ON ul.batiment_id = b.id
JOIN LATERAL (
SELECT eult.unite_logement_id,
pers1.id,
pers1.ifu,
pers1.npi,
pers1.tel1,
pers1.email,
pers1.nom,
pers1.prenom,
pers1.raison_sociale,
pers1.adresse,
eult.nombre_piscine,
eult.categorie_batiment_id,
eult.superficie_au_sol,
eult.superficie_louee,
eult.nbre_piece,
eult.date_enquete,
eult.montant_locatif_annuel_calcule,
eult.montant_locatif_annuel_declare,
eult.montant_locatif_annuel_estime,
eult.date_debut_exemption,
eult.date_fin_exemption,
eult.representant_nom,
eult.representant_prenom,
eult.representant_tel,
eult.valeur_unite_logement_reel,
eult.valeur_unite_logement_calcule,
eult.valeur_unite_logement_estime,
u.categorie_usage,
pers1.id as personne_id
FROM enquete_unite_logement eult
LEFT JOIN personne pers1 ON pers1.id = eult.personne_id
join usage u on u.id=eult.usage_id
WHERE eult.unite_logement_id = ul.id
AND eult.superficie_louee * eult.montant_locatif_annuel_declare > 0
ORDER BY date_enquete DESC, eult.id DESC
LIMIT 1
) eul ON TRUE
JOIN LATERAL (
SELECT *
FROM enquete_batiment eb2
WHERE eb2.batiment_id = b.id
ORDER BY date_enquete DESC
LIMIT 1
) eb ON TRUE
JOIN categorie_batiment cb ON cb.id = eul.categorie_batiment_id
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 st.id = v_structure_id
AND p.id=p_parcelle_id
AND NOT EXISTS(select 1 from donnees_imposition_tfu dimptfu
where dimptfu.parcelle_id=p_parcelle_id
AND dimptfu.annee=v_annee
AND dimptfu.nature_impot='IRF'
AND dimptfu.batiment_id=b.id
AND dimptfu.unite_logement_id=ul.id)
ON CONFLICT DO NOTHING;
GET DIAGNOSTICS v_rows_inserted = ROW_COUNT;
RETURN v_rows_inserted;
END;
$$;

View File

@@ -1,33 +1,36 @@
/*CREATE OR REPLACE FUNCTION public.generer_donnees_imposition_srtb_batie( CREATE OR REPLACE FUNCTION public.generer_donnees_imposition_srtb_batie(
p_impositions_tfu_id BIGINT, p_impositions_tfu_id BIGINT,
p_user_id BIGINT p_user_id BIGINT
) )
RETURNS INTEGER RETURNS INTEGER
LANGUAGE plpgsql LANGUAGE plpgsql
AS AS $$
$$
DECLARE DECLARE
v_rows_inserted INTEGER; v_rows_inserted INTEGER;
v_annee BIGINT; v_annee BIGINT;
v_structure_id BIGINT; v_structure_id BIGINT;
v_taux_defaut_sup_sol NUMERIC;
v_montant_srtb NUMERIC; v_montant_srtb NUMERIC;
v_today DATE;
BEGIN BEGIN
-- récupération de l'année v_today := CURRENT_DATE;
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;
-- -------------------------------------------------------------------------
-- 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;
select value SELECT value
into STRICT v_montant_srtb INTO STRICT v_montant_srtb
from parameters FROM parameters
where name ='TAXE_SRTB'; WHERE name = 'TAXE_SRTB';
INSERT INTO donnees_imposition_tfu (
INSERT INTO donnees_imposition_tfu(
annee, annee,
code_departement, code_departement,
nom_departement, nom_departement,
@@ -75,270 +78,21 @@ INSERT INTO donnees_imposition_tfu(
tfu_minimum, tfu_minimum,
impositions_tfu_id, impositions_tfu_id,
deleted, deleted,
created_at ,
created_by ,
"source",
updated_at ,
updated_by,
categorie_usage,
superficie_au_sol_taux_prop_parc, ---70% de la surperficie au sol de la parcelle
valeur_locative_adm_taux_prop_parc,
tfu_calcule_taux_prop_parc, ----tfu correspondant au 70%
valeur_locative_adm_sup_reel,
valeur_locative_adm, ----------valeur locative administrative
tfu_superficie_au_sol_reel, ----tfu correspondant à la superficie au sol reelle
tfu_piscine,
montant_taxe, ----tfu finale
taux_tfu, ----taux tfu batie
parcelle_id,
batiment_id,
unite_logement_id,
superficie_au_sol_loue
)
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,
(
CURRENT_DATE >= ep.date_debut_exemption
AND CURRENT_DATE <= COALESCE(ep.date_fin_exemption, CURRENT_DATE)
),
(
CURRENT_DATE >= eb.date_debut_excemption
AND CURRENT_DATE <= COALESCE(eb.date_fin_excemption, CURRENT_DATE)
),
cb.standing,
cb.nom,
eb.nombre_piscine,
eb.date_enquete,
st.id,
ep.zone_rfu_id,
'SRTB',
p.superficie,
eb.superficie_au_sol,
case -------valeur_batiment
WHEN eb.valeur_batiment_reel IS NOT NULL AND eb.valeur_batiment_reel <> 0 THEN eb.valeur_batiment_reel
WHEN eb.valeur_batiment_calcule IS NOT NULL AND eb.valeur_batiment_calcule <> 0 THEN eb.valeur_batiment_calcule
WHEN eb.valeur_batiment_estime IS NOT NULL AND eb.valeur_batiment_estime <> 0 THEN eb.valeur_batiment_estime
ELSE 0
END,
brb.valeur_locative,
case ----- montant_loyer_annuel
WHEN eb.montant_locatif_annuel_declare IS NOT NULL AND eb.montant_locatif_annuel_declare <> 0 THEN eb.montant_locatif_annuel_declare
WHEN eb.montant_locatif_annuel_calcule IS NOT NULL AND eb.montant_locatif_annuel_calcule <> 0 THEN eb.montant_locatif_annuel_calcule
WHEN eb.montant_locatif_annuel_estime IS NOT NULL AND eb.montant_locatif_annuel_estime <> 0 THEN eb.montant_locatif_annuel_estime
ELSE 0
END,
brb.tfu_metre_carre,
brb.tfu_minimum,
p_impositions_tfu_id,
false,
current_date ,
p_user_id ,
'FISCAD',
current_date ,
p_user_id,
eb.categorie_usage,
0,---superficie_au_sol_70pour100
0,
0,
eb.superficie_au_sol * brb.valeur_locative,
0, ------ valeur_locative_adm : en attente de update
0,
0,
v_montant_srtb,
0,
p.id,
b.id,
null,
eb.superficie_louee
FROM parcelle p
LEFT JOIN (
SELECT DISTINCT ON (parcelle_id)
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
ORDER BY parcelle_id, date_enquete DESC, id DESC
) ep ON ep.parcelle_id = p.id
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
--JOIN secteur_decoupage sd ON sd.quartier_id = q.id
JOIN (
SELECT DISTINCT ON (quartier_id)
quartier_id,
secteur_id
FROM secteur_decoupage
ORDER BY quartier_id
) sd ON sd.quartier_id = q.id
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
JOIN batiment b ON b.parcelle_id = p.id
JOIN (
SELECT DISTINCT ON (batiment_id)
batiment_id,
superficie_au_sol,
nombre_piscine,
categorie_batiment_id,
date_enquete,
montant_locatif_annuel_declare,
montant_locatif_annuel_calcule,
montant_locatif_annuel_estime,
date_debut_excemption,
date_fin_excemption,
valeur_batiment_reel,
valeur_batiment_calcule,
valeur_batiment_estime,
u.categorie_usage,
superficie_louee
FROM enquete_batiment eb
join usage u on u.id=eb.usage_id
ORDER BY batiment_id, date_enquete DESC, eb.id DESC
) eb ON eb.batiment_id = b.id
JOIN categorie_batiment cb
ON cb.id = eb.categorie_batiment_id
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 NOT EXISTS (
SELECT 1
FROM unite_logement ul
WHERE ul.batiment_id = b.id
)
AND st.id = v_structure_id
ON CONFLICT DO NOTHING;
GET DIAGNOSTICS v_rows_inserted = ROW_COUNT;
RETURN v_rows_inserted;
END;
$$; */
CREATE OR REPLACE FUNCTION public.generer_donnees_imposition_srtb_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_montant_srtb NUMERIC;
v_today DATE;
BEGIN
v_today := CURRENT_DATE;
-- 1. année + structure
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. paramètre (une seule requête)
SELECT value
INTO STRICT v_montant_srtb
FROM parameters
WHERE name = 'TAXE_SRTB';
-- 3. INSERT optimisé (SANS DISTINCT ON, SANS UPDATE)
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_at,
created_by, created_by,
source, "source",
updated_at, updated_at,
updated_by, updated_by,
categorie_usage, categorie_usage,
superficie_au_sol_taux_prop_parc, superficie_au_sol_taux_prop_parc, -- 70 % superficie parcelle
valeur_locative_adm_taux_prop_parc, valeur_locative_adm_taux_prop_parc,
tfu_calcule_taux_prop_parc, tfu_calcule_taux_prop_parc, -- 0 pour IRF
valeur_locative_adm_sup_reel, valeur_locative_adm_sup_reel,
valeur_locative_adm, valeur_locative_adm, -- = montant_loyer_annuel pour IRF
tfu_superficie_au_sol_reel, tfu_superficie_au_sol_reel, -- 0 pour IRF
tfu_piscine, tfu_piscine, -- 0 pour IRF
montant_taxe, montant_taxe, -- IRF finale = loyer * taux_irf
taux_tfu, taux_tfu, -- = taux_irf pour IRF
parcelle_id, parcelle_id,
batiment_id, batiment_id,
unite_logement_id, unite_logement_id,
@@ -346,146 +100,103 @@ BEGIN
personne_id personne_id
) )
SELECT SELECT
v_annee, dimp.annee,
d.code, d.nom, dimp.code_departement,
c.code, c.nom, dimp.nom_departement,
a.code, a.nom, dimp.code_commune,
q.code, q.nom, dimp.nom_commune,
p.q, p.i, p.p, p.nup, dimp.code_arrondissement,
ep.numero_titre_foncier, dimp.nom_arrondissement,
b.nub, dimp.code_quartier_village,
dimp.nom_quartier_village,
pers.ifu, pers.npi, pers.tel1, pers.email, dimp.q,
pers.nom, pers.prenom, pers.raison_sociale, pers.adresse, dimp. ilot,
ep.representant_tel, ep.representant_nom, ep.representant_prenom, dimp.parcelle,
dimp.nup,
p.longitude, p.latitude, dimp.titre_foncier,
dimp. num_batiment,
dimp.ifu,
dimp. npi,
dimp.tel_prop,
dimp.email_prop,
dimp.nom_prop,
dimp.prenom_prop,
dimp.raison_sociale,
dimp.adresse_prop,
dimp.tel_sc,
dimp.nom_sc,
dimp.prenom_sc,
dimp.longitude,
dimp.latitude,
TRUE, TRUE,
-- exonere parcelle
(v_today BETWEEN ep.date_debut_exemption AND COALESCE(ep.date_fin_exemption, v_today)), dimp.exonere,
(v_today BETWEEN eb.date_debut_excemption AND COALESCE(eb.date_fin_excemption, v_today)), -- exonere batiment
dimp.batiment_exonere,
cb.standing, dimp.standing_bat,
cb.nom, dimp.categorie_bat,
dimp.nombre_piscine,
COALESCE(eb.nombre_piscine, 0), dimp.date_enquete,
eb.date_enquete, dimp.structure_id,
dimp.zone_rfu_id,
st.id,
ep.zone_rfu_id,
'SRTB', 'SRTB',
dimp.superficie_parc,
p.superficie, dimp.superficie_au_sol_bat,
eb.superficie_au_sol, dimp.valeur_batiment,
dimp.tfu_metre_carre,
-- valeur bâtiment optimisée -- montant_loyer_annuel
COALESCE( dimp.montant_loyer_annuel,
NULLIF(eb.valeur_batiment_reel,0), -- 🔧 IRF : champs TFU mis à 0
NULLIF(eb.valeur_batiment_calcule,0), 0, -- tfu_metre_carre
NULLIF(eb.valeur_batiment_estime,0), 0, -- tfu_minimum
0
),
brb.valeur_locative,
-- loyer optimisé
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, p_impositions_tfu_id,
FALSE, FALSE,
v_today, p_user_id, 'FISCAD', v_today,
v_today, p_user_id, p_user_id,
eb.categorie_usage, 'FISCAD',
v_today,
p_user_id,
dimp.categorie_usage,
0, 0, 0, -- superficie_au_sol_taux_prop_parc (70 % parcelle)
dimp.superficie_au_sol_taux_prop_parc,
eb.superficie_au_sol * brb.valeur_locative, -- valeur_locative_adm_taux_prop_parc
dimp.valeur_locative_adm_taux_prop_parc,
0, -- 🔧 IRF : tfu_calcule_taux_prop_parc → 0
0,
0, 0,
-- 🔥 SRTB = valeur directe (pas de calcul) -- valeur_locative_adm_sup_reel
dimp.valeur_locative_adm_sup_reel,
-- ---------------------------------------------------------------
-- 🔧 IRF : valeur_locative_adm = montant_loyer_annuel (calculé directement)
-- ---------------------------------------------------------------
dimp.valeur_locative_adm
,
-- 🔧 IRF : tfu_superficie_au_sol_reel → 0
0,
-- 🔧 IRF : tfu_piscine → 0
0,
-- ---------------------------------------------------------------
-- 🔧 IRF : montant_taxe = montant_loyer_annuel * taux_irf (calculé directement)
-- ---------------------------------------------------------------
v_montant_srtb, v_montant_srtb,
-- 🔧 IRF : taux_tfu → taux_irf
0, 0,
dimp.parcelle_id,
p.id, dimp.batiment_id,
b.id, dimp.unite_logement_id,
NULL, dimp.superficie_au_sol_loue,
eb.superficie_louee, dimp.personne_id
ep.personne_id FROM donnees_imposition_tfu dimp
WHERE dimp.nature_impot= 'IRF'
FROM parcelle p AND dimp.impositions_tfu_id=p_impositions_tfu_id
-- dernière enquête parcelle
LEFT JOIN LATERAL (
SELECT *
FROM enquete e
WHERE e.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
-- structure via secteur
JOIN LATERAL (
SELECT secteur_id
FROM secteur_decoupage
WHERE quartier_id = q.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
JOIN batiment b ON b.parcelle_id = p.id
-- 🔥 remplace DISTINCT ON
JOIN LATERAL (
SELECT eb2.*,u.categorie_usage
FROM enquete_batiment eb2
LEFT 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
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 NOT EXISTS (
SELECT 1
FROM unite_logement ul
WHERE ul.batiment_id = b.id
)
AND st.id = v_structure_id
ON CONFLICT DO NOTHING; ON CONFLICT DO NOTHING;
GET DIAGNOSTICS v_rows_inserted = ROW_COUNT; GET DIAGNOSTICS v_rows_inserted = ROW_COUNT;
@@ -494,4 +205,3 @@ BEGIN
END; END;
$$; $$;

View File

@@ -0,0 +1,213 @@
CREATE OR REPLACE FUNCTION public.generer_donnees_imposition_srtb_batie_une_parcelle(
p_impositions_tfu_id BIGINT,
p_user_id BIGINT,
p_parcelle_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_montant_srtb 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;
SELECT value
INTO STRICT v_montant_srtb
FROM parameters
WHERE name = 'TAXE_SRTB';
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, -- 0 pour IRF
valeur_locative_adm_sup_reel,
valeur_locative_adm, -- = montant_loyer_annuel pour IRF
tfu_superficie_au_sol_reel, -- 0 pour IRF
tfu_piscine, -- 0 pour IRF
montant_taxe, -- IRF finale = loyer * taux_irf
taux_tfu, -- = taux_irf pour IRF
parcelle_id,
batiment_id,
unite_logement_id,
superficie_au_sol_loue,
personne_id
)
SELECT
dimp.annee,
dimp.code_departement,
dimp.nom_departement,
dimp.code_commune,
dimp.nom_commune,
dimp.code_arrondissement,
dimp.nom_arrondissement,
dimp.code_quartier_village,
dimp.nom_quartier_village,
dimp.q,
dimp. ilot,
dimp.parcelle,
dimp.nup,
dimp.titre_foncier,
dimp. num_batiment,
dimp.ifu,
dimp. npi,
dimp.tel_prop,
dimp.email_prop,
dimp.nom_prop,
dimp.prenom_prop,
dimp.raison_sociale,
dimp.adresse_prop,
dimp.tel_sc,
dimp.nom_sc,
dimp.prenom_sc,
dimp.longitude,
dimp.latitude,
TRUE,
-- exonere parcelle
dimp.exonere,
-- exonere batiment
dimp.batiment_exonere,
dimp.standing_bat,
dimp.categorie_bat,
dimp.nombre_piscine,
dimp.date_enquete,
dimp.structure_id,
dimp.zone_rfu_id,
'SRTB',
dimp.superficie_parc,
dimp.superficie_au_sol_bat,
dimp.valeur_batiment,
dimp.tfu_metre_carre,
-- montant_loyer_annuel
dimp.montant_loyer_annuel,
-- 🔧 IRF : champs TFU mis à 0
0, -- tfu_metre_carre
0, -- tfu_minimum
p_impositions_tfu_id,
FALSE,
v_today,
p_user_id,
'FISCAD',
v_today,
p_user_id,
dimp.categorie_usage,
-- superficie_au_sol_taux_prop_parc (70 % parcelle)
dimp.superficie_au_sol_taux_prop_parc,
-- valeur_locative_adm_taux_prop_parc
dimp.valeur_locative_adm_taux_prop_parc,
-- 🔧 IRF : tfu_calcule_taux_prop_parc → 0
0,
-- valeur_locative_adm_sup_reel
dimp.valeur_locative_adm_sup_reel,
-- ---------------------------------------------------------------
-- 🔧 IRF : valeur_locative_adm = montant_loyer_annuel (calculé directement)
-- ---------------------------------------------------------------
dimp.valeur_locative_adm
,
-- 🔧 IRF : tfu_superficie_au_sol_reel → 0
0,
-- 🔧 IRF : tfu_piscine → 0
0,
-- ---------------------------------------------------------------
-- 🔧 IRF : montant_taxe = montant_loyer_annuel * taux_irf (calculé directement)
-- ---------------------------------------------------------------
v_montant_srtb,
-- 🔧 IRF : taux_tfu → taux_irf
0,
dimp.parcelle_id,
dimp.batiment_id,
dimp.unite_logement_id,
dimp.superficie_au_sol_loue,
dimp.personne_id
FROM donnees_imposition_tfu dimp
WHERE dimp.nature_impot= 'IRF'
AND dimp.impositions_tfu_id=p_impositions_tfu_id
AND dimp.parcelle_id=p_parcelle_id
AND NOT EXISTS(select 1 from donnees_imposition_tfu dimptfu
where dimptfu.parcelle_id=p_parcelle_id
AND dimptfu.nature_impot='SRTB'
AND dimptfu.batiment_id=dimp.batiment_id)
ON CONFLICT DO NOTHING;
GET DIAGNOSTICS v_rows_inserted = ROW_COUNT;
RETURN v_rows_inserted;
END;
$$;

View File

@@ -1,349 +1,3 @@
/*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_valeur_locat_prof NUMERIC;
v_tfu_piscine_unitaire NUMERIC;
BEGIN
-- récupération de l'anné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;
select value
into strict v_taux_defaut_sup_sol
from parameters
where name ='TAUX_DEFAUT_SUPERFICIE_AU_SOL';
select value
into STRICT v_taux_tfu
from parameters
where name ='TAUX_TFU';
select value
into STRICT v_taux_valeur_locat_prof
from parameters
where name ='TAUX_VALEUR_LOCATIVE_PROFESSIONNELLE';
select value
into STRICT v_tfu_piscine_unitaire
from parameters
where name ='TFU_PAR_PISCINE';
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% de la surperficie au sol de la parcelle
valeur_locative_adm_taux_prop_parc,
tfu_calcule_taux_prop_parc, ----tfu correspondant au 70%
valeur_locative_adm_sup_reel,
valeur_locative_adm, ----------valeur locative administrative
tfu_superficie_au_sol_reel, ----tfu correspondant à la superficie au sol reelle
tfu_piscine,
montant_taxe, ----tfu finale
taux_tfu, ----taux tfu batie
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,
(
CURRENT_DATE >= ep.date_debut_exemption
AND CURRENT_DATE <= COALESCE(ep.date_fin_exemption, CURRENT_DATE)
),
(
CURRENT_DATE >= eb.date_debut_excemption
AND CURRENT_DATE <= COALESCE(eb.date_fin_excemption, CURRENT_DATE)
),
cb.standing,
cb.nom,
eb.nombre_piscine,
eb.date_enquete,
st.id,
ep.zone_rfu_id,
'TFU',
p.superficie,
eb.superficie_au_sol,
COALESCE(
NULLIF(eb.valeur_batiment_reel, 0),
NULLIF(eb.valeur_batiment_calcule, 0),
NULLIF(eb.valeur_batiment_estime, 0),
0
),
brb.valeur_locative,
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,
current_date ,
p_user_id ,
'FISCAD',
current_date ,
p_user_id,
eb.categorie_usage,
p.superficie*v_taux_defaut_sup_sol/100,---superficie_au_sol_70pour100
case ----valeur_locative_adm70pour100
when eb.categorie_usage = 'HABITATION' then (p.superficie * v_taux_defaut_sup_sol/100) * brb.valeur_locative
else 0
end,
case ----tfu calcule 70 pour 100 superficie parcelle
when eb.categorie_usage= 'HABITATION' then (p.superficie * v_taux_defaut_sup_sol/100) * brb.valeur_locative * v_taux_tfu/100
else 0
end,
case -----valeur_locative_adm_sup_reel
when eb.categorie_usage='HABITATION' then eb.superficie_au_sol * brb.valeur_locative
else 0
end,
0, ------ valeur_locative_adm : en attente de update
case -----tfu_superficie_au_sol_reel
when eb.categorie_usage='HABITATION' then eb.superficie_au_sol * brb.valeur_locative * v_taux_tfu/100 +eb.nombre_piscine * v_tfu_piscine_unitaire
else 0
end,
eb.nombre_piscine * v_tfu_piscine_unitaire,
0,
v_taux_tfu,
p.id,
b.id,
null
FROM parcelle p
LEFT JOIN (
SELECT DISTINCT ON (parcelle_id)
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
ORDER BY parcelle_id, date_enquete DESC, id DESC
) ep ON ep.parcelle_id = p.id
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
--JOIN secteur_decoupage sd ON sd.quartier_id = q.id
JOIN (
SELECT DISTINCT ON (quartier_id)
quartier_id,
secteur_id
FROM secteur_decoupage
ORDER BY quartier_id
) sd ON sd.quartier_id = q.id
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
JOIN batiment b ON b.parcelle_id = p.id
JOIN (
SELECT DISTINCT ON (batiment_id)
batiment_id,
superficie_au_sol,
nombre_piscine,
categorie_batiment_id,
date_enquete,
montant_locatif_annuel_declare,
montant_locatif_annuel_calcule,
montant_locatif_annuel_estime,
date_debut_excemption,
date_fin_excemption,
valeur_batiment_reel,
valeur_batiment_calcule,
valeur_batiment_estime,
u.categorie_usage
FROM enquete_batiment eb
join usage u on u.id=eb.usage_id
ORDER BY batiment_id, date_enquete DESC, eb.id DESC
) eb ON eb.batiment_id = b.id
JOIN categorie_batiment cb
ON cb.id = eb.categorie_batiment_id
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 NOT EXISTS (
SELECT 1
FROM unite_logement ul
WHERE ul.batiment_id = b.id
)
AND st.id = v_structure_id
ON CONFLICT DO NOTHING;
GET DIAGNOSTICS v_rows_inserted = ROW_COUNT;
UPDATE donnees_imposition_tfu dtfu
SET
valeur_locative_adm =
CASE
WHEN categorie_usage = 'HABITATION' AND superficie_au_sol_bat <> 0
THEN valeur_locative_adm_sup_reel
WHEN categorie_usage = 'HABITATION' AND superficie_au_sol_bat = 0
THEN valeur_locative_adm_taux_prop_parc
WHEN categorie_usage IN ('PROFESSIONNELLE','MIXTE') AND valeur_batiment <> 0
THEN valeur_batiment * (v_taux_valeur_locat_prof/100)
WHEN categorie_usage IN ('PROFESSIONNELLE','MIXTE') AND valeur_batiment = 0
THEN montant_loyer_annuel
END,
montant_taxe =
CASE
WHEN categorie_usage = 'HABITATION' AND superficie_au_sol_bat <> 0 THEN
CASE
WHEN tfu_minimum < valeur_locative_adm_sup_reel * (v_taux_tfu/100) + tfu_piscine
THEN valeur_locative_adm_sup_reel * (v_taux_tfu/100) + tfu_piscine
ELSE tfu_minimum
END
WHEN categorie_usage = 'HABITATION' AND superficie_au_sol_bat = 0 THEN
CASE
WHEN tfu_minimum < valeur_locative_adm_taux_prop_parc * (v_taux_tfu/100) + tfu_piscine
THEN valeur_locative_adm_taux_prop_parc * (v_taux_tfu/100) + tfu_piscine
ELSE tfu_minimum
END
WHEN categorie_usage IN ('PROFESSIONNELLE','MIXTE') AND valeur_batiment <> 0 THEN
CASE
WHEN tfu_minimum < valeur_batiment * (v_taux_valeur_locat_prof/100) * (v_taux_tfu/100)
THEN valeur_batiment * (v_taux_valeur_locat_prof/100) * (v_taux_tfu/100)
ELSE tfu_minimum
END
WHEN categorie_usage IN ('PROFESSIONNELLE','MIXTE') AND valeur_batiment = 0 THEN
CASE
WHEN tfu_minimum < montant_loyer_annuel * (v_taux_tfu/100)
THEN montant_loyer_annuel * (v_taux_tfu/100)
ELSE tfu_minimum
END
END
WHERE impositions_tfu_id = p_impositions_tfu_id
AND batie = TRUE
AND NOT EXISTS (
SELECT 1
FROM unite_logement ul
WHERE ul.batiment_id = dtfu.batiment_id
);
RETURN v_rows_inserted;
END;
$$;*/
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
@@ -466,12 +120,15 @@ BEGIN
valeur_locative_adm, -- valeur locative administrative finale valeur_locative_adm, -- valeur locative administrative finale
tfu_superficie_au_sol_reel, tfu_superficie_au_sol_reel,
tfu_piscine, tfu_piscine,
montant_taxe_brut,
montant_taxe, -- TFU finale montant_taxe, -- TFU finale
taux_tfu, taux_tfu,
parcelle_id, parcelle_id,
batiment_id, batiment_id,
unite_logement_id, unite_logement_id,
personne_id personne_id,
nombre_ulog,
nombre_bat
) )
SELECT SELECT
v_annee, v_annee,
@@ -515,7 +172,7 @@ BEGIN
eb.date_enquete, eb.date_enquete,
st.id, st.id,
ep.zone_rfu_id, ep.zone_rfu_id,
'TFU', 'FB',
p.superficie, p.superficie,
eb.superficie_au_sol, eb.superficie_au_sol,
-- valeur_batiment : première valeur non nulle non zéro -- valeur_batiment : première valeur non nulle non zéro
@@ -607,7 +264,48 @@ BEGIN
-- tfu_piscine -- tfu_piscine
eb.nombre_piscine * v_tfu_piscine_unitaire, eb.nombre_piscine * v_tfu_piscine_unitaire,
-- ---------------------------------------------------------------
-- montant_taxe_brut ← sans prise en compte du minimum
-- ---------------------------------------------------------------
(
-- 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 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 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 calc.vb * v_taux_vlp_ratio * v_taux_tfu_ratio
WHEN eb.categorie_usage IN ('PROFESSIONNELLE', 'MIXTE')
AND calc.vb = 0
THEN calc.loyer * v_taux_tfu_ratio
ELSE brb.tfu_minimum
END
FROM calc
),
-- --------------------------------------------------------------- -- ---------------------------------------------------------------
-- montant_taxe ← calculé directement (plus d'UPDATE) -- montant_taxe ← calculé directement (plus d'UPDATE)
-- Utilise des CTE inline via expression pour éviter la redondance -- Utilise des CTE inline via expression pour éviter la redondance
@@ -658,7 +356,13 @@ BEGIN
p.id, p.id,
b.id, b.id,
NULL, NULL,
ep.personne_id ep.personne_id,
(select count(*)
from unite_logement ulog
where ulog.batiment_id= b.id),
(select count(*)
from batiment bat
where bat.parcelle_id= p.id)
FROM parcelle p FROM parcelle p
-- Dernière enquête parcelle -- Dernière enquête parcelle
LEFT JOIN LATERAL ( LEFT JOIN LATERAL (
@@ -742,10 +446,10 @@ BEGIN
) brb ON TRUE ) brb ON TRUE
WHERE p.batie = TRUE WHERE p.batie = TRUE
AND ul_filter.batiment_id IS NULL -- anti-join : pas d'unité logement --AND ul_filter.batiment_id IS NULL -- anti-join : pas d'unité logement
AND st.id = v_structure_id AND st.id = v_structure_id ;
ON CONFLICT DO NOTHING; -- ON CONFLICT DO NOTHING;
GET DIAGNOSTICS v_rows_inserted = ROW_COUNT; GET DIAGNOSTICS v_rows_inserted = ROW_COUNT;

View File

@@ -0,0 +1,464 @@
CREATE OR REPLACE FUNCTION public.generer_donnees_imposition_tfu_batie_une_parcelle(
p_impositions_tfu_id BIGINT,
p_user_id BIGINT,
p_parcelle_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_brut,
montant_taxe, -- TFU finale
taux_tfu,
parcelle_id,
batiment_id,
unite_logement_id,
personne_id,
nombre_ulog,
nombre_bat
)
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,
'FB',
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 * eb.nombre_piscine * v_tfu_piscine_unitaire
ELSE 0
END,
-- tfu_piscine
eb.nombre_piscine * v_tfu_piscine_unitaire,
-- ---------------------------------------------------------------
-- montant_taxe_brut ← sans prise en compte du minimum
-- ---------------------------------------------------------------
(
-- 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 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 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 calc.vb * v_taux_vlp_ratio * v_taux_tfu_ratio
WHEN eb.categorie_usage IN ('PROFESSIONNELLE', 'MIXTE')
AND calc.vb = 0
THEN calc.loyer * v_taux_tfu_ratio
ELSE brb.tfu_minimum
END
FROM calc
),
-- ---------------------------------------------------------------
-- 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,
ep.personne_id,
(select count(*)
from unite_logement ulog
where ulog.batiment_id= b.id),
(select count(*)
from batiment bat
where bat.parcelle_id= p.id)
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
AND p.id = p_parcelle_id
AND NOT EXISTS(select 1 from donnees_imposition_tfu dimptfu
where dimptfu.batiment_id=b.id
and dimptfu.annee=v_annee
and dimptfu.nature_impot='FB');
-- ON CONFLICT DO NOTHING;
GET DIAGNOSTICS v_rows_inserted = ROW_COUNT;
RETURN v_rows_inserted;
END;
$$;

View File

@@ -1,398 +1,3 @@
/*CREATE OR REPLACE FUNCTION public.generer_donnees_imposition_tfu_batie_unite_logement(
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_valeur_locat_prof NUMERIC;
v_tfu_piscine_unitaire NUMERIC;
BEGIN
-- récupération de l'anné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;
select value
into strict v_taux_defaut_sup_sol
from parameters
where name ='TAUX_DEFAUT_SUPERFICIE_AU_SOL';
select value
into STRICT v_taux_tfu
from parameters
where name ='TAUX_TFU';
RAISE NOTICE 'v_taux_tfu = %', v_taux_tfu;
select value
into STRICT v_taux_valeur_locat_prof
from parameters
where name ='TAUX_VALEUR_LOCATIVE_PROFESSIONNELLE';
select value
into STRICT v_tfu_piscine_unitaire
from parameters
where name ='TFU_PAR_PISCINE';
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,
num_unite_logement,
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,
unite_logement_exonere,
standing_bat,
categorie_bat,
nombre_piscine,
date_enquete,
structure_id,
zone_rfu_id,
nature_impot,
superficie_parc,
superficie_au_sol_bat,
superficie_au_sol_ulog,
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% de la surperficie au sol de la parcelle
valeur_locative_adm_taux_prop_parc,
tfu_calcule_taux_prop_parc, ----tfu correspondant au 70%
valeur_locative_adm_sup_reel,
valeur_locative_adm, ----------valeur locative administrative
tfu_superficie_au_sol_reel, ----tfu correspondant à la superficie au sol reelle
tfu_piscine,
montant_taxe, ----tfu finale
taux_tfu, ----taux tfu batie
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,
ul.nul,
eul.ifu,
eul.npi,
eul.tel1,
eul.email,
eul.nom,
eul.prenom,
eul.raison_sociale,
eul.adresse,
eul.representant_tel,
eul.representant_nom,
eul.representant_prenom,
p.longitude,
p.latitude,
TRUE,
(
CURRENT_DATE >= ep.date_debut_exemption
AND CURRENT_DATE <= COALESCE(ep.date_fin_exemption, CURRENT_DATE)
),
(
CURRENT_DATE >= eb.date_debut_excemption
AND CURRENT_DATE <= COALESCE(eb.date_fin_excemption, CURRENT_DATE)
),
(
CURRENT_DATE >= eul.date_debut_exemption
AND CURRENT_DATE <= COALESCE(eul.date_fin_exemption, CURRENT_DATE)
),
cb.standing,
cb.nom,
CASE
WHEN eul.nombre_piscine is null then 0
else eul.nombre_piscine
END,
eul.date_enquete,
st.id,
ep.zone_rfu_id,
'TFU',
p.superficie,
eb.superficie_au_sol,
eul.superficie_au_sol,
CASE -------valeur_batiment
WHEN eul.valeur_unite_logement_reel IS NOT NULL AND eul.valeur_unite_logement_reel <> 0 THEN eul.valeur_unite_logement_reel
WHEN eul.valeur_unite_logement_calcule IS NOT NULL AND eul.valeur_unite_logement_calcule <> 0 THEN eul.valeur_unite_logement_calcule
WHEN eul.valeur_unite_logement_estime IS NOT NULL AND eul.valeur_unite_logement_estime <> 0 THEN eul.valeur_unite_logement_estime
ELSE 0
END,
brb.valeur_locative,
CASE ----- montant_loyer_annuel
WHEN eul.montant_locatif_annuel_declare IS NOT NULL AND eul.montant_locatif_annuel_declare <> 0 THEN eul.montant_locatif_annuel_declare
WHEN eul.montant_locatif_annuel_calcule IS NOT NULL AND eul.montant_locatif_annuel_calcule <> 0 THEN eul.montant_locatif_annuel_calcule
WHEN eul.montant_locatif_annuel_estime IS NOT NULL AND eul.montant_locatif_annuel_estime <> 0 THEN eul.montant_locatif_annuel_estime
ELSE 0
END,
brb.tfu_metre_carre,
brb.tfu_minimum,
p_impositions_tfu_id,
false,
current_date,
p_user_id,
'FISCAD',
current_date,
p_user_id,
eul.categorie_usage,
p.superficie * v_taux_defaut_sup_sol/100,---superficie_au_sol_70pour100
case ----valeur_locative_adm70pour100
when eul.categorie_usage = 'HABITATION' then (p.superficie * v_taux_defaut_sup_sol/100) * brb.valeur_locative
else 0
end,
case ----tfu calcule 70 pour 100 superficie parcelle
when eul.categorie_usage= 'HABITATION' then (p.superficie * v_taux_defaut_sup_sol/100) * brb.valeur_locative * v_taux_tfu/100
else 0
end,
case -----valeur_locative_adm_sup_reel
when eul.categorie_usage='HABITATION' then eul.superficie_au_sol * brb.valeur_locative
else 0
end,
0, ------ valeur_locative_adm : en attente de update
case -----tfu_superficie_au_sol_reel
when eul.categorie_usage='HABITATION' then eul.superficie_au_sol * brb.valeur_locative * 6/100
else 0
end,
CASE
WHEN eul.nombre_piscine is null then 0
else eul.nombre_piscine * v_tfu_piscine_unitaire
END,
0,
v_taux_tfu,
p.id,
b.id,
ul.id
FROM parcelle p
LEFT JOIN (
SELECT DISTINCT ON (parcelle_id)
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
ORDER BY parcelle_id, date_enquete DESC, id DESC
) ep ON ep.parcelle_id = p.id
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
--JOIN secteur_decoupage sd ON sd.quartier_id = q.id
JOIN (
SELECT DISTINCT ON (quartier_id)
quartier_id,
secteur_id
FROM secteur_decoupage
ORDER BY quartier_id
) sd ON sd.quartier_id = q.id
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
JOIN batiment b ON b.parcelle_id = p.id
JOIN (
SELECT DISTINCT ON (batiment_id)
batiment_id,
superficie_au_sol,
nombre_piscine,
categorie_batiment_id,
date_enquete,
montant_locatif_annuel_declare,
montant_locatif_annuel_calcule,
montant_locatif_annuel_estime,
date_debut_excemption,
date_fin_excemption,
valeur_batiment_reel,
valeur_batiment_calcule,
valeur_batiment_estime,
u.categorie_usage
FROM enquete_batiment eb
join usage u on u.id=eb.usage_id
ORDER BY batiment_id, date_enquete DESC, eb.id DESC
) eb ON eb.batiment_id = b.id
JOIN unite_logement ul on ul.batiment_id = b.id
JOIN (
SELECT DISTINCT ON (eult.unite_logement_id)
eult.unite_logement_id,
pers1.id,
pers1.ifu,
pers1.npi,
pers1.tel1,
pers1.email,
pers1.nom,
pers1.prenom,
pers1.raison_sociale,
pers1.adresse,
eult.nombre_piscine,
eult.categorie_batiment_id,
eult.superficie_au_sol,
eult.superficie_louee,
eult.nbre_piece,
eult.date_enquete,
eult.montant_locatif_annuel_calcule,
eult.montant_locatif_annuel_declare,
eult.montant_locatif_annuel_estime,
eult.date_debut_exemption,
eult.date_fin_exemption,
eult.representant_nom,
eult.representant_prenom,
eult.representant_tel,
eult.valeur_unite_logement_reel,
eult.valeur_unite_logement_calcule,
eult.valeur_unite_logement_estime,
u.categorie_usage
FROM enquete_unite_logement eult
join usage u on u.id=eult.usage_id
left join personne pers1 on pers1.id = eult.personne_id
ORDER BY unite_logement_id, date_enquete DESC, eult.id DESC
) eul ON eul.unite_logement_id = ul.id
JOIN categorie_batiment cb
ON cb.id = eul.categorie_batiment_id
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 EXISTS (
SELECT 1
FROM unite_logement ul
WHERE ul.batiment_id = b.id
)
AND st.id = v_structure_id
ON CONFLICT DO NOTHING;
GET DIAGNOSTICS v_rows_inserted = ROW_COUNT;
UPDATE donnees_imposition_tfu dtfu
SET
valeur_locative_adm =
CASE
WHEN categorie_usage = 'HABITATION' AND superficie_au_sol_ulog <> 0
THEN valeur_locative_adm_sup_reel
WHEN categorie_usage = 'HABITATION' AND superficie_au_sol_ulog = 0
THEN valeur_locative_adm_taux_prop_parc
WHEN categorie_usage IN ('PROFESSIONNELLE','MIXTE') AND valeur_batiment <> 0
THEN valeur_batiment * (v_taux_valeur_locat_prof/100)
WHEN categorie_usage IN ('PROFESSIONNELLE','MIXTE') AND valeur_batiment = 0
THEN montant_loyer_annuel
END,
montant_taxe =
CASE
WHEN categorie_usage = 'HABITATION' AND superficie_au_sol_ulog <> 0 THEN
CASE
WHEN tfu_minimum < valeur_locative_adm_sup_reel * (v_taux_tfu/100) + tfu_piscine
THEN valeur_locative_adm_sup_reel * (v_taux_tfu/100) + tfu_piscine
ELSE tfu_minimum
END
WHEN categorie_usage = 'HABITATION' AND superficie_au_sol_ulog = 0 THEN
CASE
WHEN tfu_minimum < valeur_locative_adm_taux_prop_parc * (v_taux_tfu/100) + tfu_piscine
THEN valeur_locative_adm_taux_prop_parc * (v_taux_tfu/100) + tfu_piscine
ELSE tfu_minimum
END
WHEN categorie_usage IN ('PROFESSIONNELLE','MIXTE') AND valeur_batiment <> 0 THEN
CASE
WHEN tfu_minimum < valeur_batiment * (v_taux_valeur_locat_prof/100) * (v_taux_tfu/100)
THEN valeur_batiment * (v_taux_valeur_locat_prof/100) * (v_taux_tfu/100)
ELSE tfu_minimum
END
WHEN categorie_usage IN ('PROFESSIONNELLE','MIXTE') AND valeur_batiment = 0 THEN
CASE
WHEN tfu_minimum < montant_loyer_annuel * (v_taux_tfu/100)
THEN montant_loyer_annuel * (v_taux_tfu/100)
ELSE tfu_minimum
END
END
WHERE impositions_tfu_id = p_impositions_tfu_id
AND batie = TRUE
AND EXISTS (
SELECT 1
FROM unite_logement ul
WHERE ul.batiment_id = dtfu.batiment_id
);
RETURN v_rows_inserted;
END;
$$;*/
CREATE OR REPLACE FUNCTION public.generer_donnees_imposition_tfu_batie_unite_logement( CREATE OR REPLACE FUNCTION public.generer_donnees_imposition_tfu_batie_unite_logement(
p_impositions_tfu_id BIGINT, p_impositions_tfu_id BIGINT,
p_user_id BIGINT p_user_id BIGINT
@@ -446,6 +51,8 @@ BEGIN
'TFU_PAR_PISCINE' 'TFU_PAR_PISCINE'
); );
-- Ratios pré-calculés pour éviter la division répétée dans le SELECT -- 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_tfu_ratio := v_taux_tfu / 100.0;
v_taux_vlp_ratio := v_taux_valeur_locat_prof / 100.0; v_taux_vlp_ratio := v_taux_valeur_locat_prof / 100.0;
@@ -454,6 +61,27 @@ BEGIN
-- 3. INSERT avec calcul complet de valeur_locative_adm et montant_taxe -- 3. INSERT avec calcul complet de valeur_locative_adm et montant_taxe
-- → supprime l'UPDATE post-INSERT (économie d'un second scan de table) -- → supprime l'UPDATE post-INSERT (économie d'un second scan de table)
-- ------------------------------------------------------------------------- -- -------------------------------------------------------------------------
WITH uniteLogementSupTotal as (
WITH derniere_enquete_ulog AS (
SELECT
eul.*,
ROW_NUMBER() OVER (
PARTITION BY unite_logement_id
ORDER BY date_enquete DESC
) AS rn
FROM enquete_unite_logement eul
)
SELECT
ul.batiment_id,
dimp.montant_taxe,
SUM(ulog.superficie_au_sol) AS superficie_totale
FROM derniere_enquete_ulog ulog
inner join unite_logement ul on ul.id=ulog.unite_logement_id
inner join donnees_imposition_tfu dimp on dimp.batiment_id= ul.batiment_id
WHERE rn = 1
AND dimp.impositions_tfu_id = p_impositions_tfu_id
GROUP BY ul.batiment_id,dimp.montant_taxe
)
INSERT INTO donnees_imposition_tfu ( INSERT INTO donnees_imposition_tfu (
annee, annee,
code_departement, code_departement,
@@ -570,7 +198,7 @@ BEGIN
eul.date_enquete, eul.date_enquete,
st.id, st.id,
ep.zone_rfu_id, ep.zone_rfu_id,
'TFU', 'FB',
p.superficie, p.superficie,
eb.superficie_au_sol, eb.superficie_au_sol,
eul.superficie_au_sol, eul.superficie_au_sol,
@@ -620,7 +248,6 @@ BEGIN
THEN eul.superficie_au_sol * brb.valeur_locative THEN eul.superficie_au_sol * brb.valeur_locative
ELSE 0 ELSE 0
END, END,
-- --------------------------------------------------------------- -- ---------------------------------------------------------------
-- valeur_locative_adm avec tests explicites (corrigée) -- valeur_locative_adm avec tests explicites (corrigée)
-- --------------------------------------------------------------- -- ---------------------------------------------------------------
@@ -654,7 +281,6 @@ BEGIN
ELSE 0 ELSE 0
END, END,
-- 🔧 CORRECTION : tfu_superficie_au_sol_reel (était hardcodé à 6/100) -- 🔧 CORRECTION : tfu_superficie_au_sol_reel (était hardcodé à 6/100)
CASE WHEN eul.categorie_usage = 'HABITATION' CASE WHEN eul.categorie_usage = 'HABITATION'
THEN eul.superficie_au_sol * brb.valeur_locative * v_taux_tfu_ratio THEN eul.superficie_au_sol * brb.valeur_locative * v_taux_tfu_ratio
@@ -667,56 +293,16 @@ BEGIN
-- --------------------------------------------------------------- -- ---------------------------------------------------------------
-- montant_taxe ← calculé directement (plus d'UPDATE) -- montant_taxe ← calculé directement (plus d'UPDATE)
-- --------------------------------------------------------------- -- ---------------------------------------------------------------
( case when ulost.superficie_totale > 0
WITH calc AS ( then eul.superficie_au_sol * ulost.montant_taxe / ulost.superficie_totale
SELECT else 0
COALESCE(NULLIF(eul.valeur_unite_logement_reel, 0), end,
NULLIF(eul.valeur_unite_logement_calcule, 0),
NULLIF(eul.valeur_unite_logement_estime, 0), 0) AS valeur_ul,
COALESCE(NULLIF(eul.montant_locatif_annuel_declare, 0),
NULLIF(eul.montant_locatif_annuel_calcule, 0),
NULLIF(eul.montant_locatif_annuel_estime, 0), 0) AS loyer,
eul.superficie_au_sol * brb.valeur_locative AS vla_reel,
(p.superficie * v_taux_defaut_sup_sol / 100.0)
* brb.valeur_locative AS vla_70,
COALESCE(eul.nombre_piscine, 0) * v_tfu_piscine_unitaire AS piscine_montant
)
SELECT
CASE
WHEN eul.categorie_usage = 'HABITATION'
AND eul.superficie_au_sol <> 0
THEN GREATEST(brb.tfu_minimum,
calc.vla_reel * v_taux_tfu_ratio
+ calc.piscine_montant)
WHEN eul.categorie_usage = 'HABITATION'
AND eul.superficie_au_sol = 0
THEN GREATEST(brb.tfu_minimum,
calc.vla_70 * v_taux_tfu_ratio
+ calc.piscine_montant)
WHEN eul.categorie_usage IN ('PROFESSIONNELLE', 'MIXTE')
AND calc.valeur_ul <> 0
THEN GREATEST(brb.tfu_minimum,
calc.valeur_ul * v_taux_vlp_ratio * v_taux_tfu_ratio)
WHEN eul.categorie_usage IN ('PROFESSIONNELLE', 'MIXTE')
AND calc.valeur_ul = 0
THEN GREATEST(brb.tfu_minimum,
calc.loyer * v_taux_tfu_ratio)
ELSE brb.tfu_minimum
END
FROM calc
),
v_taux_tfu, v_taux_tfu,
p.id, p.id,
b.id, b.id,
ul.id ul.id
FROM parcelle p FROM parcelle p
-- Dernière enquête parcelle -- Dernière enquête parcelle
LEFT JOIN LATERAL ( LEFT JOIN LATERAL (
SELECT SELECT
@@ -784,6 +370,7 @@ BEGIN
) eb ON TRUE ) eb ON TRUE
JOIN unite_logement ul ON ul.batiment_id = b.id JOIN unite_logement ul ON ul.batiment_id = b.id
INNER JOIN uniteLogementSupTotal ulost on ulost.batiment_id=ul.batiment_id
-- Dernière enquête unité logement -- Dernière enquête unité logement
JOIN LATERAL ( JOIN LATERAL (

View File

@@ -0,0 +1,448 @@
CREATE OR REPLACE FUNCTION public.generer_donnees_imposition_tfu_batie_ulo_une_parcelle(
p_impositions_tfu_id BIGINT,
p_user_id BIGINT,
p_parcelle_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)
-- -------------------------------------------------------------------------
WITH uniteLogementSupTotal as (
WITH derniere_enquete_ulog AS (
SELECT
eul.*,
ROW_NUMBER() OVER (
PARTITION BY unite_logement_id
ORDER BY date_enquete DESC
) AS rn
FROM enquete_unite_logement eul
)
SELECT
ul.batiment_id,
dimp.montant_taxe,
SUM(ulog.superficie_au_sol) AS superficie_totale
FROM derniere_enquete_ulog ulog
inner join unite_logement ul on ul.id=ulog.unite_logement_id
inner join donnees_imposition_tfu dimp on dimp.batiment_id= ul.batiment_id
WHERE rn = 1
AND dimp.impositions_tfu_id = p_impositions_tfu_id
GROUP BY ul.batiment_id,dimp.montant_taxe
)
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,
num_unite_logement,
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,
unite_logement_exonere,
standing_bat,
categorie_bat,
nombre_piscine,
date_enquete,
structure_id,
zone_rfu_id,
nature_impot,
superficie_parc,
superficie_au_sol_bat,
superficie_au_sol_ulog,
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,
ul.nul,
eul.ifu,
eul.npi,
eul.tel1,
eul.email,
eul.nom,
eul.prenom,
eul.raison_sociale,
eul.adresse,
eul.representant_tel,
eul.representant_nom,
eul.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)),
-- exonere unite logement
(v_today BETWEEN eul.date_debut_exemption
AND COALESCE(eul.date_fin_exemption, v_today)),
cb.standing,
cb.nom,
COALESCE(eul.nombre_piscine, 0),
eul.date_enquete,
st.id,
ep.zone_rfu_id,
'FB',
p.superficie,
eb.superficie_au_sol,
eul.superficie_au_sol,
-- valeur_batiment (unité logement) : première valeur non nulle non zéro
COALESCE(
NULLIF(eul.valeur_unite_logement_reel, 0),
NULLIF(eul.valeur_unite_logement_calcule, 0),
NULLIF(eul.valeur_unite_logement_estime, 0),
0
),
brb.valeur_locative,
-- montant_loyer_annuel
COALESCE(
NULLIF(eul.montant_locatif_annuel_declare, 0),
NULLIF(eul.montant_locatif_annuel_calcule, 0),
NULLIF(eul.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,
eul.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 eul.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 eul.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 eul.categorie_usage = 'HABITATION'
THEN eul.superficie_au_sol * brb.valeur_locative
ELSE 0
END,
-- ---------------------------------------------------------------
-- valeur_locative_adm avec tests explicites (corrigée)
-- ---------------------------------------------------------------
CASE
WHEN eul.categorie_usage = 'HABITATION'
AND eul.superficie_au_sol <> 0
THEN eul.superficie_au_sol * brb.valeur_locative
WHEN eul.categorie_usage = 'HABITATION'
AND eul.superficie_au_sol = 0
THEN (p.superficie * v_taux_defaut_sup_sol / 100.0) * brb.valeur_locative
-- ✅ Test explicite : valeur_unite_logement <> 0
WHEN eul.categorie_usage IN ('PROFESSIONNELLE', 'MIXTE')
AND COALESCE(NULLIF(eul.valeur_unite_logement_reel, 0),
NULLIF(eul.valeur_unite_logement_calcule, 0),
NULLIF(eul.valeur_unite_logement_estime, 0), 0) <> 0
THEN COALESCE(NULLIF(eul.valeur_unite_logement_reel, 0),
NULLIF(eul.valeur_unite_logement_calcule, 0),
NULLIF(eul.valeur_unite_logement_estime, 0), 0)
* v_taux_vlp_ratio
-- ✅ Test explicite : valeur_unite_logement = 0
WHEN eul.categorie_usage IN ('PROFESSIONNELLE', 'MIXTE')
AND COALESCE(NULLIF(eul.valeur_unite_logement_reel, 0),
NULLIF(eul.valeur_unite_logement_calcule, 0),
NULLIF(eul.valeur_unite_logement_estime, 0), 0) = 0
THEN COALESCE(NULLIF(eul.montant_locatif_annuel_declare, 0),
NULLIF(eul.montant_locatif_annuel_calcule, 0),
NULLIF(eul.montant_locatif_annuel_estime, 0), 0)
ELSE 0
END,
-- 🔧 CORRECTION : tfu_superficie_au_sol_reel (était hardcodé à 6/100)
CASE WHEN eul.categorie_usage = 'HABITATION'
THEN eul.superficie_au_sol * brb.valeur_locative * v_taux_tfu_ratio
ELSE 0
END,
-- tfu_piscine
COALESCE(eul.nombre_piscine, 0) * v_tfu_piscine_unitaire,
-- ---------------------------------------------------------------
-- montant_taxe ← calculé directement (plus d'UPDATE)
-- ---------------------------------------------------------------
case when ulost.superficie_totale > 0
then eul.superficie_au_sol * ulost.montant_taxe / ulost.superficie_totale
else 0
end,
v_taux_tfu,
p.id,
b.id,
ul.id
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
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
JOIN batiment b ON b.parcelle_id = p.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 unite_logement ul ON ul.batiment_id = b.id
INNER JOIN uniteLogementSupTotal ulost on ulost.batiment_id=ul.batiment_id
-- Dernière enquête unité logement
JOIN LATERAL (
SELECT
eul2.unite_logement_id,
pers1.id,
pers1.ifu,
pers1.npi,
pers1.tel1,
pers1.email,
pers1.nom,
pers1.prenom,
pers1.raison_sociale,
pers1.adresse,
eul2.nombre_piscine,
eul2.categorie_batiment_id,
eul2.superficie_au_sol,
eul2.superficie_louee,
eul2.nbre_piece,
eul2.date_enquete,
eul2.montant_locatif_annuel_calcule,
eul2.montant_locatif_annuel_declare,
eul2.montant_locatif_annuel_estime,
eul2.date_debut_exemption,
eul2.date_fin_exemption,
eul2.representant_nom,
eul2.representant_prenom,
eul2.representant_tel,
eul2.valeur_unite_logement_reel,
eul2.valeur_unite_logement_calcule,
eul2.valeur_unite_logement_estime,
u.categorie_usage
FROM enquete_unite_logement eul2
JOIN usage u ON u.id = eul2.usage_id
LEFT JOIN personne pers1 ON pers1.id = eul2.personne_id
WHERE eul2.unite_logement_id = ul.id
ORDER BY eul2.date_enquete DESC, eul2.id DESC
LIMIT 1
) eul ON TRUE
JOIN categorie_batiment cb ON cb.id = eul.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 EXISTS (
SELECT 1
FROM unite_logement ul2
WHERE ul2.batiment_id = b.id
)
AND st.id = v_structure_id
AND p.id = p_parcelle_id
AND NOT exists(select 1 from donnees_imposition_tfu dimptfu
where dimptfu.annee=v_annee
and dimptfu.batiment_id=b.id
and dimptfu.unite_logement_id=ul.id
and dimptfu.nature_impot='FB')
ON CONFLICT DO NOTHING;
GET DIAGNOSTICS v_rows_inserted = ROW_COUNT;
RETURN v_rows_inserted;
END;
$$;

View File

@@ -268,7 +268,7 @@ BEGIN
ep.date_enquete, ep.date_enquete,
st.id, st.id,
ep.zone_rfu_id, ep.zone_rfu_id,
'TFU', 'FNB',
p.superficie, p.superficie,
p_impositions_tfu_id, p_impositions_tfu_id,
false, false,

View File

@@ -0,0 +1,190 @@
CREATE OR REPLACE FUNCTION public.generer_donnees_imposition_tfu_non_batie_une_parcelle(
p_impositions_tfu_id BIGINT,
p_user_id BIGINT,
p_parcelle_id BIGINT
)
RETURNS INTEGER
LANGUAGE plpgsql
AS
$$
DECLARE
v_rows_inserted INTEGER;
v_annee BIGINT;
v_structure_id BIGINT;
BEGIN
-- récupération de l'anné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;
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,
ifu,
npi,
tel_prop,
email_prop,
nom_prop,
prenom_prop,
raison_sociale,
adresse_prop,
tel_sc,
nom_sc,
prenom_sc,
longitude,
latitude,
batie,
exonere,
date_enquete,
structure_id,
zone_rfu_id,
nature_impot,
superficie_parc,
impositions_tfu_id,
deleted,
created_at,
created_by,
"source",
updated_at,
updated_by,
taux_tfu,
valeur_admin_parcelle_nb,
valeur_admin_parcelle_nb_metre_carre,
montant_taxe,
parcelle_id,
personne_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,
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,
false,
(
CURRENT_DATE >= ep.date_debut_exemption
AND CURRENT_DATE <= COALESCE(ep.date_fin_exemption, CURRENT_DATE)
),
ep.date_enquete,
st.id,
ep.zone_rfu_id,
'FNB',
p.superficie,
p_impositions_tfu_id,
false,
current_date,
p_user_id,
'FISCAD',
current_date,
p_user_id,
brnb.taux,
CASE
WHEN brnb.au_metre_carre = true
THEN brnb.valeur_administrative_metre_carre * ep.superficie
ELSE brnb.valeur_administrative
END,
brnb.valeur_administrative_metre_carre,
CASE
WHEN brnb.au_metre_carre = true
THEN brnb.valeur_administrative_metre_carre * ep.superficie * brnb.taux / 100
ELSE brnb.valeur_administrative * brnb.taux / 100
END,
p.id,
ep.personne_id
FROM parcelle p
LEFT JOIN (
SELECT DISTINCT ON (parcelle_id)
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
ORDER BY parcelle_id, date_enquete DESC
) ep ON ep.parcelle_id = p.id
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
-- ✅ CORRECTION ICI
JOIN (
SELECT DISTINCT ON (quartier_id)
quartier_id,
secteur_id
FROM secteur_decoupage
ORDER BY quartier_id
) sd ON sd.quartier_id = q.id
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
LEFT JOIN barem_rfu_non_bati brnb
ON (brnb.commune_id = c.id AND brnb.zone_rfu_id = ep.zone_rfu_id)
WHERE p.batie = false
AND st.id = v_structure_id
AND p.id=p_parcelle_id
AND NOT EXISTS( select 1 from donnees_imposition_tfu dimptfu
where dimptfu.nature_impot='FNB'
and dimptfu.parcelle_id=p_parcelle_id
and dimptfu.annee=v_annee)
ON CONFLICT DO NOTHING;
GET DIAGNOSTICS v_rows_inserted = ROW_COUNT;
RETURN v_rows_inserted;
END;
$$;

View File

@@ -0,0 +1,95 @@
SELECT dblink_connect(
'connexion_rfu',
'host=10.4.6.103 port=5432 dbname=rfu user=postgres password=Rfu@dm1N2@25TeMp0'
);
--SELECT dblink_disconnect('connexion_rfu');
--SELECT pg_size_pretty(pg_database_size('rfu'));
CREATE OR REPLACE PROCEDURE public.import_assignation_centre_personne_from_rfu_cotonou()
LANGUAGE plpgsql
AS $procedure$
BEGIN
INSERT INTO public.commune_centre_assignation (
nc,
ifu,
commune_id,
structure_id,
personne_id,
parcelle_id,
created_at,
created_by,
deleted,
updated_at,
updated_by,
source
)
SELECT
c.n0_contrib,
c.ifu,
70,
case rcdi
when 'A' then 61
when 'B' then 62
when 'C' then 63
when 'D' then 64
else null
end,
pers.id,
parc.id,
now(),
NULL::bigint,
false,
now(),
NULL::bigint,
'RFU'
FROM dblink(
'connexion_rfu',
$db$
SELECT distinct on (ifu,rcdi)
trim(ifu),
trim(n0_contrib),
trim(rcdi),
trim(quartier_c),
trim(ilot_c),
trim(parcel_c)
FROM stemichel.contrib
order by ifu,rcdi
$db$
) AS c (
ifu varchar,
n0_contrib varchar,
rcdi varchar,
quartier_c varchar,
ilot_c varchar,
parcel_c varchar
)
LEFT JOIN personne pers on trim(pers.ifu)=trim(c.ifu)
LEFT JOIN parcelle parc on (trim(parc.q) = trim(c.quartier_c)
and trim(parc.i) = trim(c.ilot_c)
and trim(parc.p) = trim(c.parcel_c))
WHERE NOT EXISTS (
SELECT 1
FROM public.commune_centre_assignation cca
WHERE cca.personne_id = pers.id
and cca.structure_id = case trim(c.rcdi)
when 'A' then 61
when 'B' then 62
when 'C' then 63
when 'D' then 64
else null
end
and cca.commune_id = 70
)
ON CONFLICT (structure_id, commune_id, personne_id) DO NOTHING;
END;
$procedure$;
call import_assignation_centre_personne_from_rfu_cotonou();
--delete from commune_centre_assignation;
--select * from commune_centre_assignation;

View File

@@ -0,0 +1,99 @@
SELECT dblink_connect(
'connexion_rfu',
'host=10.4.6.103 port=5432 dbname=rfu user=postgres password=Rfu@dm1N2@25TeMp0'
);
CREATE OR REPLACE PROCEDURE public.import_imposition_rfu_cotonou(in exercice varchar(10), in nombreLimit numeric)
LANGUAGE plpgsql
AS $procedure$
DECLARE
l_count numeric := 0;
imposition_rfu record;
l_parcelle_id_parent bigint;
l_code_quartier varchar(20);
BEGIN
FOR imposition_rfu IN (
SELECT FROM dblink(
'connexion_rfu',
$db$
SELECT
i.article ,
i.ifu ,
i.n0_contrib ,
i.denome ,
i.annees ,
i.nature ,
n.libnature ,
i.quartier,
q.libquart ,
i.n0_ilot ,
i.n0_parcel ,
i.nn,
COALESCE(i.montant,0) droit_simple,
COALESCE(i.penalite,0) penalite,
COALESCE(i.majorat,0) majoration,
COALESCE(i.montant,0)+COALESCE(i.penalite,0)+COALESCE(i.majorat,0) total_imposition
FROM stemichel.impotsra i
join agla.nature n on n.nature=i.nature
left join (select distinct
n0_ilot,
quartier,
libquart
from agla.quartier)q on (q.n0_ilot=i.n0_ilot and q.quartier=i.quartier)
-- WHERE i.annees = '2025' or (i.annees ='2024' and trim(i.nature) in ('3N', '4N', 'YN'))
limit 100
$db$
) AS c (
terrain varchar,
n0_ilot varchar,
n0_parcel varchar,
quartier varchar,
hauteur varchar,
rue varchar,
entree varchar,
vlcalcule varchar,
vllcalcule varchar,
)
WHERE NOT EXISTS (
SELECT 1
FROM public.parcelle p
WHERE p.numero_parcelle =
trim(c.quartier)||'-'||trim(c.n0_ilot)||'-'||trim(c.n0_parcel)
) and exists (
select 1
from public.ref_rfu_q_quartier_cotonou rq
where rq.rfu_q = trim(c.quartier)
)
limit nombreLimit
) LOOP
BEGIN
INSERT INTO parcelle (
created_at,
created_by,
deleted,
updated_at,
updated_by,
parcelle_id,
source
)
SELECT
now(),
35,
false,
now(),
35,
parcelle_id,
'RFU'
FROM ref_rfu_q_quartier_cotonou rq
WHERE rq.rfu_q = parcelle_rfu.q
RETURNING id, code_quartier
INTO l_parcelle_id_parent, l_code_quartier;
RAISE NOTICE 'Nombre impositions migrées : %', l_count;
END ;
END LOOP ;
END;
$procedure$;

View File

@@ -0,0 +1,103 @@
/**
- recuperation et cumul des acomptes par exercice, commune, ifu et parcelle
- recuperation et cumul des rirf par exercice, commune, ifu et parcelle
*/
CREATE OR REPLACE FUNCTION public.maj_donnees_imposition_tfu_irf_(
p_impositions_tfu_id BIGINT
)
RETURNS INTEGER
LANGUAGE plpgsql
AS $$
DECLARE
v_rows_inserted INTEGER;
v_annee INTEGER;
v_structure_id INTEGER;
BEGIN
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;
WITH cumulRetenu as (
select ifu_retenue,
r_commune,
r_quartier,
qip_quartier,
qip_ilot,
qip_parcelle,
nup,
exercice,
sum(montant_payer) as cumul_retenu
from epaiement_retenu
where exercice = v_annee
group by ifu_retenue, r_commune, r_quartier,
qip_quartier, qip_ilot, qip_parcelle,
nup, exercice
)
UPDATE donnees_imposition_tfu dimp
SET
retenu_irf = coalesce(cr.cumul_retenu,0),
montant_restant = dimp.montant_taxe
- coalesce(cr.cumul_retenu,0)
FROM donnees_imposition_tfu dimp2
LEFT JOIN cumulRetenu cr ON (
cr.exercice = dimp2.annee
AND cr.r_commune = dimp2.code_commune
AND cr.ifu_retenue = dimp2.ifu
AND cr.r_quartier = dimp2.code_quartier_village
AND cr.qip_quartier = dimp2.q
AND cr.qip_ilot = dimp2.ilot
AND cr.qip_parcelle = dimp2.parcelle
AND cr.nup = dimp2.nup
AND cr.nup = dimp2.nup
)
WHERE dimp.id = dimp2.id
AND dimp.impositions_tfu_id = p_impositions_tfu_id
AND dimp.nature_impot ='IRF';
WITH cumulAcompte as (
select ifu,
r_commune,
r_quartier,
qip_quartier,
qip_ilot,
qip_parcelle,
nup,
exercice,
sum(montant_payer) as cumul_acompte
from epaiement_acompte
where exercice = v_annee
group by ifu, r_commune, r_quartier,
qip_quartier, qip_ilot, qip_parcelle,
nup, exercice
)
UPDATE donnees_imposition_tfu dimp
SET
acompte = coalesce(ac.cumul_acompte,0),
montant_restant = dimp.montant_taxe
- coalesce(ac.cumul_acompte,0)
FROM donnees_imposition_tfu dimp2
LEFT JOIN cumulAcompte ac ON (
ac.exercice = dimp2.annee
AND ac.r_commune = dimp2.code_commune
AND ac.ifu = dimp2.ifu
AND ac.r_quartier = dimp2.code_quartier_village
AND ac.qip_quartier = dimp2.q
AND ac.qip_ilot = dimp2.ilot
AND ac.qip_parcelle = dimp2.parcelle
AND ac.nup = dimp2.nup
)
WHERE dimp.id = dimp2.id
AND dimp.impositions_tfu_id = p_impositions_tfu_id
AND dimp.nature_impot in ('FNB','FB');
GET DIAGNOSTICS v_rows_inserted = ROW_COUNT;
RETURN v_rows_inserted;
END;
$$ ;

View File

@@ -0,0 +1,51 @@
/**
- consider les parcelles avec plusieurs batiment
- faire la somme (som_tfu_calcule) des TFU calculées
- on recupere la tfu minimum (max_tfu_min) de la catégorie la plus élévée des batiment
- si montant_tfu= Max(som_tfu_calcule, max_tfu_min)
*/
CREATE OR REPLACE FUNCTION public.maj_donnees_imposition_tfu_batie_plusBati(
p_impositions_tfu_id BIGINT
)
RETURNS INTEGER
LANGUAGE plpgsql
AS $$
DECLARE
v_rows_inserted INTEGER;
BEGIN
------MAJ pour les parcelles ayants plusieurs batiment
WITH donnees_imposition_plusieurs_bat AS (
SELECT
dimp.parcelle_id,
GREATEST(
MAX(dimp.tfu_minimum),
SUM(dimp.montant_taxe_brut)
) AS montant_tfu_parcelle,
COUNT(*) AS nombre_bat
FROM donnees_imposition_tfu dimp
LEFT JOIN unite_logement ul_filter on dimp.unite_logement_id = ul_filter.id
where impositions_tfu_id=p_impositions_tfu_id
AND batie=true and ul_filter.id is null
AND nature_impot='FB'
GROUP BY dimp.parcelle_id
HAVING COUNT(*) > 1
)
UPDATE donnees_imposition_tfu dimp
SET
montant_taxe = dippb.montant_tfu_parcelle,
nombre_bat = dippb.nombre_bat
FROM donnees_imposition_plusieurs_bat dippb
WHERE dimp.parcelle_id = dippb.parcelle_id
AND dimp.impositions_tfu_id=p_impositions_tfu_id;
------FIN MAJ pour les parcelles ayants plusieurs batiment
GET DIAGNOSTICS v_rows_inserted = ROW_COUNT;
RETURN v_rows_inserted;
END;
$$;

View File

@@ -0,0 +1,53 @@
/**
- consider les parcelles avec plusieurs batiment
- faire la somme (som_tfu_calcule) des TFU calculées
- on recupere la tfu minimum (max_tfu_min) de la catégorie la plus élévée des batiment
- si montant_tfu= Max(som_tfu_calcule, max_tfu_min)
*/
CREATE OR REPLACE FUNCTION public.maj_donnees_imposition_tfu_batie_plusBati_une_parcelle(
p_impositions_tfu_id BIGINT,
p_parcelle_id BIGINT
)
RETURNS INTEGER
LANGUAGE plpgsql
AS $$
DECLARE
v_rows_inserted INTEGER;
BEGIN
------MAJ pour les parcelles ayants plusieurs batiment
WITH donnees_imposition_plusieurs_bat AS (
SELECT
dimp.parcelle_id,
GREATEST(
MAX(dimp.tfu_minimum),
SUM(dimp.montant_taxe_brut)
) AS montant_tfu_parcelle,
COUNT(*) AS nombre_bat
FROM donnees_imposition_tfu dimp
LEFT JOIN unite_logement ul_filter on dimp.unite_logement_id = ul_filter.id
where impositions_tfu_id=p_impositions_tfu_id
AND batie=true and ul_filter.id is null
AND nature_impot='FB'
AND dimp.parcelle_id=p_parcelle_id
GROUP BY dimp.parcelle_id
HAVING COUNT(*) > 1
)
UPDATE donnees_imposition_tfu dimp
SET
montant_taxe = dippb.montant_tfu_parcelle,
nombre_bat = dippb.nombre_bat
FROM donnees_imposition_plusieurs_bat dippb
WHERE dimp.parcelle_id = dippb.parcelle_id
AND dimp.impositions_tfu_id=p_impositions_tfu_id;
------FIN MAJ pour les parcelles ayants plusieurs batiment
GET DIAGNOSTICS v_rows_inserted = ROW_COUNT;
RETURN v_rows_inserted;
END;
$$;

View File

@@ -263,4 +263,36 @@ public interface PersonneRepository extends JpaRepository<Personne, Long> {
List<PersonnePayLoadWeb> findAllPersonneByNpiToDto( List<PersonnePayLoadWeb> findAllPersonneByNpiToDto(
@Param("npi") String npi @Param("npi") String npi
); );
@Query(value = """
SELECT new io.gmss.fiscad.paylaods.request.crudweb.PersonnePayLoadWeb(
p.id,
p.ifu,
p.nom,
p.prenom,
p.raisonSociale,
p.numRavip,
p.npi,
p.dateNaissanceOuConsti,
p.lieuNaissance,
p.tel1,
p.nomJeuneFille,
p.nomMere,
p.etatIdentificationPersonne
)
FROM Personne p
where not exists (
select 1 from CommuneCentreAssignation cca
where cca.personne.id=p.id)
""",
countQuery = """
SELECT COUNT(p)
FROM Personne p
where not exists (
select 1 from CommuneCentreAssignation cca
where cca.personne.id=p.id)
"""
)
Page<PersonnePayLoadWeb> findAllPersonneNonAssigneCentreToDto(Pageable pageable);
} }

View File

@@ -0,0 +1,304 @@
package io.gmss.fiscad.persistence.repositories.rfu.metier;
import io.gmss.fiscad.entities.rfu.metier.Batiment;
import io.gmss.fiscad.entities.rfu.metier.CommuneCentreAssignation;
import io.gmss.fiscad.paylaods.request.crudweb.BatimentPaylaodWeb;
import io.gmss.fiscad.paylaods.request.crudweb.CommuneCentreAssignationPaylaodWeb;
import io.gmss.fiscad.paylaods.response.restoration.BatimentPayloadRestor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
import java.util.Optional;
public interface CommuneCentreAssignationRepository extends JpaRepository<CommuneCentreAssignation, Long> {
@Query(
value = """
SELECT new io.gmss.fiscad.paylaods.request.crudweb.CommuneCentreAssignationPaylaodWeb(
cca.id,
c.id,
c.code,
c.nom,
s.id,
s.code,
s.nom,
p.id,
p.nom,
p.prenom,
p.raisonSociale,
p.ifu,
p.nc,
p.npi,
parc.id,
q.code,
parc.q,
parc.i,
parc.p,
cca.adresseContact
)
FROM CommuneCentreAssignation cca
LEFT JOIN cca.commune c
LEFT JOIN cca.structure s
LEFT JOIN cca.personne p
LEFT JOIN cca.parcelle parc
LEFT JOIN parc.quartier q
""",
countQuery = """
SELECT COUNT(cca.id)
FROM CommuneCentreAssignation cca
"""
)
Page<CommuneCentreAssignationPaylaodWeb> findAllPayload(Pageable pageable);
@Query(
value = """
SELECT new io.gmss.fiscad.paylaods.request.crudweb.CommuneCentreAssignationPaylaodWeb(
cca.id,
c.id,
c.code,
c.nom,
s.id,
s.code,
s.nom,
p.id,
p.nom,
p.prenom,
p.raisonSociale,
p.ifu,
p.nc,
p.npi,
parc.id,
q.code,
parc.q,
parc.i,
parc.p,
cca.adresseContact
)
FROM CommuneCentreAssignation cca
JOIN cca.structure s
LEFT JOIN cca.commune c
LEFT JOIN cca.personne p
LEFT JOIN cca.parcelle parc
LEFT JOIN parc.quartier q
WHERE s.id = :structureId
""",
countQuery = """
SELECT COUNT(cca.id)
FROM CommuneCentreAssignation cca
WHERE cca.structure.id = :structureId
"""
)
Page<CommuneCentreAssignationPaylaodWeb> findByStructureId(
Long structureId,
Pageable pageable
);
@Query(
value = """
SELECT new io.gmss.fiscad.paylaods.request.crudweb.CommuneCentreAssignationPaylaodWeb(
cca.id,
c.id,
c.code,
c.nom,
s.id,
s.code,
s.nom,
p.id,
p.nom,
p.prenom,
p.raisonSociale,
p.ifu,
p.nc,
p.npi,
parc.id,
q.code,
parc.q,
parc.i,
parc.p,
cca.adresseContact
)
FROM CommuneCentreAssignation cca
JOIN cca.commune c
LEFT JOIN cca.structure s
LEFT JOIN cca.personne p
LEFT JOIN cca.parcelle parc
LEFT JOIN parc.quartier q
WHERE c.id = :communeId
""",
countQuery = """
SELECT COUNT(cca.id)
FROM CommuneCentreAssignation cca
WHERE cca.commune.id = :communeId
"""
)
Page<CommuneCentreAssignationPaylaodWeb> findByCommuneId(
Long communeId,
Pageable pageable
);
@Query(
value = """
SELECT new io.gmss.fiscad.paylaods.request.crudweb.CommuneCentreAssignationPaylaodWeb(
cca.id,
c.id,
c.code,
c.nom,
s.id,
s.code,
s.nom,
p.id,
p.nom,
p.prenom,
p.raisonSociale,
p.ifu,
p.nc,
p.npi,
parc.id,
q.code,
parc.q,
parc.i,
parc.p,
cca.adresseContact
)
FROM CommuneCentreAssignation cca
JOIN cca.structure s
JOIN cca.commune c
LEFT JOIN cca.personne p
LEFT JOIN cca.parcelle parc
LEFT JOIN parc.quartier q
WHERE s.id = :structureId
AND c.id = :communeId
""",
countQuery = """
SELECT COUNT(cca.id)
FROM CommuneCentreAssignation cca
WHERE cca.structure.id = :structureId
AND cca.commune.id = :communeId
"""
)
Page<CommuneCentreAssignationPaylaodWeb> findByStructureAndCommune(
Long structureId,
Long communeId,
Pageable pageable
);
@Query("""
SELECT new io.gmss.fiscad.paylaods.request.crudweb.CommuneCentreAssignationPaylaodWeb(
cca.id,
c.id,
c.code,
c.nom,
s.id,
s.code,
s.nom,
p.id,
p.nom,
p.prenom,
p.raisonSociale,
p.ifu,
p.nc,
p.npi,
parc.id,
q.code,
parc.q,
parc.i,
parc.p,
cca.adresseContact
)
FROM CommuneCentreAssignation cca
JOIN cca.structure s
JOIN cca.commune c
JOIN cca.personne p
LEFT JOIN cca.parcelle parc
LEFT JOIN parc.quartier q
WHERE s.id = :structureId
AND c.id = :communeId
AND p.id = :personneId
""")
Optional<CommuneCentreAssignationPaylaodWeb> findUnique(
Long structureId,
Long communeId,
Long personneId
);
@Query("""
SELECT new io.gmss.fiscad.paylaods.request.crudweb.CommuneCentreAssignationPaylaodWeb(
cca.id,
c.id,
c.code,
c.nom,
s.id,
s.code,
s.nom,
p.id,
p.nom,
p.prenom,
p.raisonSociale,
p.ifu,
p.nc,
p.npi,
parc.id,
q.code,
parc.q,
parc.i,
parc.p,
cca.adresseContact
)
FROM CommuneCentreAssignation cca
JOIN cca.structure s
JOIN cca.commune c
JOIN cca.personne p
LEFT JOIN cca.parcelle parc
LEFT JOIN parc.quartier q
WHERE cca.id = :id
""")
Optional<CommuneCentreAssignationPaylaodWeb> findUnique(
Long id
);
@Query("""
SELECT new io.gmss.fiscad.paylaods.request.crudweb.CommuneCentreAssignationPaylaodWeb(
cca.id,
c.id,
c.code,
c.nom,
s.id,
s.code,
s.nom,
p.id,
p.nom,
p.prenom,
p.raisonSociale,
p.ifu,
p.nc,
p.npi,
parc.id,
q.code,
parc.q,
parc.i,
parc.p,
cca.adresseContact
)
FROM CommuneCentreAssignation cca
JOIN cca.structure s
JOIN cca.commune c
JOIN cca.personne p
LEFT JOIN cca.parcelle parc
LEFT JOIN parc.quartier q
WHERE c.id = :communeId
AND p.id = :personneId
""")
Optional<CommuneCentreAssignationPaylaodWeb> findbyCommuneAndPersonne(
Long communeId,
Long personneId
);
}

View File

@@ -28,7 +28,12 @@ public interface DeclarationNcRepository extends JpaRepository<DeclarationNc, Lo
p.nom, p.nom,
p.prenom, p.prenom,
p.raisonSociale, p.raisonSociale,
d.observation d.observation,
d.q,
d.i,
d.p,
d.numeroTitreFoncier,
d.nup
) )
FROM DeclarationNc d FROM DeclarationNc d
LEFT JOIN d.structure s LEFT JOIN d.structure s
@@ -50,7 +55,12 @@ public interface DeclarationNcRepository extends JpaRepository<DeclarationNc, Lo
p.nom, p.nom,
p.prenom, p.prenom,
p.raisonSociale, p.raisonSociale,
d.observation d.observation,
d.q,
d.i,
d.p,
d.numeroTitreFoncier,
d.nup
) )
FROM DeclarationNc d FROM DeclarationNc d
LEFT JOIN d.structure s LEFT JOIN d.structure s
@@ -71,7 +81,12 @@ public interface DeclarationNcRepository extends JpaRepository<DeclarationNc, Lo
p.nom, p.nom,
p.prenom, p.prenom,
p.raisonSociale, p.raisonSociale,
d.observation d.observation,
d.q,
d.i,
d.p,
d.numeroTitreFoncier,
d.nup
) )
FROM DeclarationNc d FROM DeclarationNc d
LEFT JOIN d.structure s LEFT JOIN d.structure s
@@ -93,7 +108,12 @@ public interface DeclarationNcRepository extends JpaRepository<DeclarationNc, Lo
p.nom, p.nom,
p.prenom, p.prenom,
p.raisonSociale, p.raisonSociale,
d.observation d.observation,
d.q,
d.i,
d.p,
d.numeroTitreFoncier,
d.nup
) )
FROM DeclarationNc d FROM DeclarationNc d
LEFT JOIN d.structure s LEFT JOIN d.structure s
@@ -116,7 +136,12 @@ public interface DeclarationNcRepository extends JpaRepository<DeclarationNc, Lo
p.nom, p.nom,
p.prenom, p.prenom,
p.raisonSociale, p.raisonSociale,
d.observation d.observation,
d.q,
d.i,
d.p,
d.numeroTitreFoncier,
d.nup
) )
FROM DeclarationNc d FROM DeclarationNc d
LEFT JOIN d.structure s LEFT JOIN d.structure s
@@ -135,4 +160,34 @@ public interface DeclarationNcRepository extends JpaRepository<DeclarationNc, Lo
Pageable pageable Pageable pageable
); );
@Query("""
SELECT distinct new io.gmss.fiscad.paylaods.request.crudweb.DeclarationNcPayloadWeb(
d.id,
d.dateDerniereDeclaration,
d.dateDeclarationNc,
d.nc,
s.id,
s.code,
s.nom,
p.id,
p.nom,
p.prenom,
p.raisonSociale,
d.observation,
d.q,
d.i,
d.p,
d.numeroTitreFoncier,
d.nup
)
FROM DeclarationNc d
LEFT JOIN d.structure s
LEFT JOIN d.personne p
WHERE d.nc= :nc
and p.id <> :personneId
""")
List<DeclarationNcPayloadWeb> findAllDeclarationNcByNcNotPersonneToDto(@Param("nc") String nc, @Param("personneId") Long personneId);
} }

View File

@@ -508,53 +508,115 @@ SELECT new io.gmss.fiscad.paylaods.request.crudweb.DonneesImpositionPaylaodWeb(
Pageable pageable Pageable pageable
); );
@Query(value = "SELECT generer_donnees_imposition_tfu_batie(:structureId, :impositionId)", nativeQuery = true) @Query(value = "SELECT generer_donnees_imposition_tfu_batie(:impositionId, :userId)", nativeQuery = true)
Integer genererDonneesTfuBatie( Integer genererDonneesTfuBatie(
@Param("structureId") Long structureId, @Param("impositionId") Long impositionId,
@Param("impositionId") Long impositionId @Param("userId") Long userId
);
@Query(value = "SELECT generer_donnees_imposition_tfu_batie_une_parcelle(:impositionId, :userId,:parcelleId)", nativeQuery = true)
Integer genererDonneesTfuBatie(
@Param("impositionId") Long impositionId,
@Param("userId") Long userId,
@Param("parcelleId") Long parcelleId
); );
@Query(value = "SELECT generer_donnees_imposition_tfu_batie_unite_logement(:structureId, :impositionId)", nativeQuery = true) @Query(value = "SELECT generer_donnees_imposition_tfu_batie_unite_logement(:impositionId, :userId)", nativeQuery = true)
Integer genererDonneesTfuBatieUniteLogement( Integer genererDonneesTfuBatieUniteLogement(
@Param("structureId") Long structureId, @Param("impositionId") Long impositionId,
@Param("impositionId") Long impositionId @Param("userId") Long userId
);
@Query(value = "SELECT generer_donnees_imposition_tfu_batie_ulo_une_parcelle(:impositionId, :userId,:parcelleId)", nativeQuery = true)
Integer genererDonneesTfuBatieUniteLogement(
@Param("impositionId") Long impositionId,
@Param("userId") Long userId,
@Param("parcelleId") Long parcelleId
); );
@Query(value = "SELECT generer_donnees_imposition_tfu_non_batie(:structureId, :impositionId)", nativeQuery = true) @Query(value = "SELECT generer_donnees_imposition_tfu_non_batie(:impositionId, :userId)", nativeQuery = true)
Integer genererDonneesTfuNonBatie( Integer genererDonneesTfuNonBatie(
@Param("structureId") Long structureId, @Param("impositionId") Long impositionId,
@Param("impositionId") Long impositionId @Param("userId") Long userId
); );
@Query(value = "SELECT generer_donnees_imposition_irf_batie(:structureId, :impositionId)", nativeQuery = true) @Query(value = "SELECT generer_donnees_imposition_tfu_non_batie_une_parcelle(:impositionId, :userId, :parcelleId)", nativeQuery = true)
Integer genererDonneesTfuNonBatie(
@Param("impositionId") Long impositionId,
@Param("userId") Long userId,
@Param("parcelleId") Long parcelleId
);
@Query(value = "SELECT generer_donnees_imposition_irf_batie(:impositionId, :userId)", nativeQuery = true)
Integer genererDonneesIrfBatie( Integer genererDonneesIrfBatie(
@Param("structureId") Long structureId, @Param("impositionId") Long impositionId,
@Param("impositionId") Long impositionId @Param("userId") Long userId
); );
@Query(value = "SELECT generer_donnees_imposition_srtb_batie(:structureId, :impositionId)", nativeQuery = true) @Query(value = "SELECT generer_donnees_imposition_irf_batie_une_parcelle(:impositionId, :userId, :parcelleId)", nativeQuery = true)
Integer genererDonneesIrfBatie(
@Param("impositionId") Long impositionId,
@Param("userId") Long userId,
@Param("parcelleId") Long parcelleId
);
@Query(value = "SELECT generer_donnees_imposition_srtb_batie(:impositionId, :userId)", nativeQuery = true)
Integer genererDonneesSrtbBatie( Integer genererDonneesSrtbBatie(
@Param("structureId") Long structureId, @Param("impositionId") Long impositionId,
@Param("impositionId") Long impositionId @Param("userId") Long userId
); );
@Query(value = "SELECT generer_donnees_imposition_irf_batie_unite_logement(:structureId, :impositionId)", nativeQuery = true) @Query(value = "SELECT generer_donnees_imposition_srtb_batie_une_parcelle(:impositionId, :userId, :parcelleId)", nativeQuery = true)
Integer genererDonneesSrtbBatie(
@Param("impositionId") Long impositionId,
@Param("userId") Long userId,
@Param("parcelleId") Long parcelleId
);
@Query(value = "SELECT generer_donnees_imposition_irf_batie_unite_logement(:impositionId, :userId)", nativeQuery = true)
Integer genererDonneesIrfBatieUniteLogement( Integer genererDonneesIrfBatieUniteLogement(
@Param("structureId") Long structureId, @Param("impositionId") Long impositionId,
@Param("userId") Long userId
);
@Query(value = "SELECT generer_donnees_imposition_irf_batie_ulo_une_parcelle(:impositionId, :userId, :parcelleId)", nativeQuery = true)
Integer genererDonneesIrfBatieUniteLogement(
@Param("impositionId") Long impositionId,
@Param("userId") Long userId,
@Param("parcelleId") Long parcelleId
);
// @Query(value = "SELECT generer_donnees_imposition_srtb_batie_unite_logement(:impositionId, :userId)", nativeQuery = true)
// Integer genererDonneesSrtbBatieUniteLogement(
// @Param("impositionId") Long impositionId,
// @Param("userId") Long userId
// );
// @Query(value = "SELECT generer_donnees_imposition_srtb_batie_u(:impositionId, :userId)", nativeQuery = true)
// Integer genererDonneesSrtbBatieUniteLogement(
// @Param("impositionId") Long impositionId,
// @Param("userId") Long userId
// );
@Query(value = "SELECT maj_donnees_imposition_tfu_batie_plusBati(:impositionId)", nativeQuery = true)
Integer majDonneesTfuBatiePlusieursBatiment(
@Param("impositionId") Long impositionId @Param("impositionId") Long impositionId
); );
@Query(value = "SELECT generer_donnees_imposition_srtb_batie_unite_logement(:structureId, :impositionId)", nativeQuery = true) @Query(value = "SELECT maj_donnees_imposition_tfu_batie_plusbati_une_parcelle(:impositionId,:parcelleId)", nativeQuery = true)
Integer genererDonneesSrtbBatieUniteLogement( Integer majDonneesTfuBatiePlusieursBatiment(
@Param("structureId") Long structureId, @Param("impositionId") Long impositionId,
@Param("impositionId") Long impositionId @Param("parcelleId") Long parcelleId
); );
@Query(value = """ @Query(value = """
SELECT new io.gmss.fiscad.paylaods.request.crudweb.DonneesImpositionPaylaodWeb( SELECT new io.gmss.fiscad.paylaods.request.crudweb.DonneesImpositionPaylaodWeb(
d.id, d.id,

View File

@@ -74,6 +74,7 @@ public class EntityFromPayLoadService {
private final RueRepository rueRepository ; private final RueRepository rueRepository ;
private final NatureDomaineRepository natureDomaineRepository ; private final NatureDomaineRepository natureDomaineRepository ;
private final TypeDomaineRepository typeDomaineRepository ; private final TypeDomaineRepository typeDomaineRepository ;
private final CommuneCentreAssignationRepository communeCentreAssignationRepository ;
public CaracteristiqueParcelle getCaracteristiqueParcelleFromPayLoadWeb(CaracteristiqueParcellePayloadWeb caracteristiqueParcellePayloadWeb){ public CaracteristiqueParcelle getCaracteristiqueParcelleFromPayLoadWeb(CaracteristiqueParcellePayloadWeb caracteristiqueParcellePayloadWeb){
@@ -210,6 +211,11 @@ public class EntityFromPayLoadService {
declarationNc.setStructure(optionalStructure.orElse(null)); declarationNc.setStructure(optionalStructure.orElse(null));
declarationNc.setPersonne(optionalPersonne.orElse(null)); declarationNc.setPersonne(optionalPersonne.orElse(null));
declarationNc.setNc(declarationNcPayloadWeb.getNc()); declarationNc.setNc(declarationNcPayloadWeb.getNc());
declarationNc.setQ(declarationNcPayloadWeb.getQ());
declarationNc.setI(declarationNcPayloadWeb.getI());
declarationNc.setP(declarationNcPayloadWeb.getP());
declarationNc.setNumeroTitreFoncier(declarationNcPayloadWeb.getNumeroTitreFoncier());
declarationNc.setNup(declarationNcPayloadWeb.getNup());
declarationNc.setDateDerniereDeclaration(declarationNcPayloadWeb.getDateDerniereDeclaration()); declarationNc.setDateDerniereDeclaration(declarationNcPayloadWeb.getDateDerniereDeclaration());
declarationNc.setDateDeclarationNc(declarationNcPayloadWeb.getDateDeclarationNc()); declarationNc.setDateDeclarationNc(declarationNcPayloadWeb.getDateDeclarationNc());
return declarationNc ; return declarationNc ;
@@ -997,4 +1003,38 @@ public class EntityFromPayLoadService {
parcelle.setSuperficie(parcellePayLoadWeb.getSuperficie()); parcelle.setSuperficie(parcellePayLoadWeb.getSuperficie());
return parcelle; return parcelle;
} }
public CommuneCentreAssignation getCommuneCentreAssignationFromPayLoadWeb(CommuneCentreAssignationPaylaodWeb communeCentreAssignationPaylaodWeb) {
CommuneCentreAssignation communeCentreAssignation = new CommuneCentreAssignation();
if (communeCentreAssignationPaylaodWeb.getId()!=null)
communeCentreAssignation=communeCentreAssignationRepository.findById(communeCentreAssignationPaylaodWeb.getId()).orElse(new CommuneCentreAssignation());
if (communeCentreAssignationPaylaodWeb.getPersonneId() != null) {
Personne personne = new Personne();
personne.setId(communeCentreAssignationPaylaodWeb.getPersonneId());
communeCentreAssignation.setPersonne(personne);
}
communeCentreAssignation.setAdresseContact(communeCentreAssignationPaylaodWeb.getAdresseContact());
// if (communeCentreAssignationPaylaodWeb.getCommuneId() != null) {
// Commune commune = new Commune();
// commune.setId(communeCentreAssignationPaylaodWeb.getCommuneId());
// communeCentreAssignation.setCommune(commune);
// }
// if (communeCentreAssignationPaylaodWeb.getStructureId() != null) {
// Structure structure = new Structure();
// structure.setId(communeCentreAssignationPaylaodWeb.getStructureId());
// communeCentreAssignation.setStructure(structure);
// }
if (communeCentreAssignationPaylaodWeb.getParcelleContactId() != null) {
Parcelle parcelle = new Parcelle();
parcelle.setId(communeCentreAssignationPaylaodWeb.getParcelleContactId());
communeCentreAssignation.setParcelle(parcelle);
}
return communeCentreAssignation;
}
} }