<severityHelios></severityHelios>
</message>
<message id="MCOM39" ctrlId="COMM12">
- <regleFonctionnelle>Les comptes Nature, Fonction et Opération doivent être renseignés selon le parmètrage de la collectivité dans XéMèLios</regleFonctionnelle>
+ <regleFonctionnelle>Les comptes Nature, Fonction et Opération doivent être renseignés selon le parmètrage de la collectivité dans XéMèLios si le type de pièce est différent de "ORMC"</regleFonctionnelle>
<regleTechnique>Si PAR1 différent M21 et M 22 et PAR 2 = Fonction, toutes les lignes doivent avoir l'information LigneDePiece/ BlocLignePiece/ InfoLignePce/ Fonction renseignée et la balise Opération ne doit pas être valorisée</regleTechnique>
<libelle>Pour un vote par Fonction (autre que M21 et M22), le code fonction doit être valorisé et le code opération doit être absent</libelle>
<severity>BLOQUANT</severity>
<severityHelios></severityHelios>
</message>
<message id="MCOM40" ctrlId="COMM12">
- <regleFonctionnelle>Les comptes Nature, Fonction et Opération doivent être renseignés selon le parmètrage de la collectivité dans XéMèLios</regleFonctionnelle>
+ <regleFonctionnelle>Les comptes Nature, Fonction et Opération doivent être renseignés selon le parmètrage de la collectivité dans XéMèLios si le type de pièce est différent de "ORMC"</regleFonctionnelle>
<regleTechnique>Si on trouve les informations LigneDePiece/BlocLignePiece/InfoLignePce/Nature, Fonction et Opération, alors on doit trouver les paramétrages PAR1 différents de M21 et M22, PAR2 == "Nature avec réf. Fonctionnelle" et PAR 3 = OUI</regleTechnique>
<libelle>Les informations récupérées du flux (Imputation, Fonction et Opération) ne correspondent pas au paramétrage effectué (Vote : Nature avec référence fonctionnelle et suivi par Opération)</libelle>
<severity>BLOQUANT</severity>
<message id="MDEP03" ctrlId="DEP02">
<regleFonctionnelle>L'imputation doit être en concordance avec le triplet et inversement</regleFonctionnelle>
<regleTechnique>Si au moins une Piece/ LigneDePiece/ BlocLignePiece/ InfoLignePce/ Nature[@V] vaut 64*, 621*, 631*, 633* et TypBord=01, alors NatPce=11</regleTechnique>
- <libelle>Une ligne du mandat (TypBord 01) contient un compte du chapitre 012 (64*, 621*, 631* ou 633*) alors la nature du mandat doit être valorisée à PAIE (NatPce 11)</libelle>
+ <libelle>Si une ligne du mandat (TypBord 01) contient un compte 64*, 621*, 631* ou 633*, alors la nature du mandat doit être valorisée à PAIE (NatPce 11) ou MARCHE ( TypPce 09 )</libelle>
<severity>BLOQUANT</severity>
<severityHelios></severityHelios>
</message>
<severityHelios></severityHelios>
</message>
<message id="MREC25" ctrlId="REC14">
- <regleFonctionnelle>Les comptes Nature, Fonction et Opération doivent être renseignés selon le parmètrage de la collectivité dans XéMéLios</regleFonctionnelle>
+ <regleFonctionnelle>Les comptes Nature, Fonction et Opération doivent être renseignés selon le parmètrage de la collectivité dans XéMéLios si le type de pièce est différent de "ORMC"</regleFonctionnelle>
<regleTechnique>Si PAR1 = M52 et PAR 2 = Fonction, PAR3 = false, la balise LigneDePiece/ BlocLignePiece/ InfoLignePce/ Fonction doit être renseignée selon la valeur décrite dans l'onglet Code_fonction et la balise Opération ne doit pas être valorisée. C'est le code fonction qui porte le numéro de l'opération</regleTechnique>
<libelle>En M52 par fonction : le code fonction dédié doit être servi pour un titre au compte 753X</libelle>
- <severity>BLOQUANT</severity>
- <severityHelios></severityHelios>
+ <severity>NON BLOQUANT</severity>
+ <severityHelios>NON BLOQUANT</severityHelios>
</message>
<message id="MREC26" ctrlId="REC15">
<regleFonctionnelle>L'imputation doit être en concordance avec le triplet et inversement</regleFonctionnelle>
<severityHelios></severityHelios>
</message>
<message id="MREC41" ctrlId="REC19">
- <regleFonctionnelle>Le triplet Type de bordereau / Nature du titre / Type du titre doit être cohérent</regleFonctionnelle>
+ <regleFonctionnelle>Le triplet Type de bordereau / Nature du titre / Type du titre doit être cohérent si le type de pièce est différent de "ORMC"</regleFonctionnelle>
<regleTechnique>Toute combinaison ne faisant pas partie de la table de référencement rec_triplet.xls ne doit pas être utilisée</regleTechnique>
<libelle>Le triplet type bordereau/ type de pièce / Nature de pièce ne fait pas parti des possibilités existantes dans le tableau des triplets "Domaine Recette"</libelle>
<severity>BLOQUANT</severity>
<severityHelios></severityHelios>
</message>
+
+ <message id="MREC42" ctrlId="REC20">
+ <regleFonctionnelle>Si le bordereau est de type ORMC (balise TypBord = ORMC), alors toutes les pièces incluses dans le bordereau doivent être de type ORMC (balise TypPiece = ORMC).</regleFonctionnelle>
+ <regleTechnique>Un bordereau d'ORMC ne peut contenir que des pièces de type ORMC.</regleTechnique>
+ <libelle>Un bordereau d'ORMC ne peut contenir que des pièces de type ORMC.</libelle>
+ <severity>BLOQUANT</severity>
+ <severityHelios></severityHelios>
+ </message>
+ <message id="MREC43" ctrlId="REC20">
+ <regleFonctionnelle>Si la pièce est de type ORMC (balise TypPce = ORMC), alors le bordereau est de type ORMC (balise TypBord = ORMC).</regleFonctionnelle>
+ <regleTechnique>Un ORMC ne peut être rattaché qu'à un bordereau de type ORMC.</regleTechnique>
+ <libelle>Un ORMC ne peut être rattaché qu'à un bordereau de type ORMC.</libelle>
+ <severity>BLOQUANT</severity>
+ <severityHelios></severityHelios>
+ </message>
+ <message id="MREC44" ctrlId="REC20">
+ <regleFonctionnelle>Si la pièce est de type ORMC (balise TypPce = ORMC), alors toutes les lignes de titres rattachées doivent avoir pour type tiers " débiteur principal " (01), le même nom, le même prénom, la même date de naissance si celle-ci est servie, le même code postal et la même ville.</regleFonctionnelle>
+ <regleTechnique>Un ORMC doit être mono débiteur.</regleTechnique>
+ <libelle>Un ORMC doit être mono débiteur.</libelle>
+ <severity>BLOQUANT</severity>
+ <severityHelios></severityHelios>
+ </message>
+ <message id="MREC45" ctrlId="REC20">
+ <regleFonctionnelle>Si la pièce est de type ORMC (balise TypPce = ORMC), et si au moins une ligne de titre rattachée possède une information de prélèvement servi, alors toutes les lignes de titres rattachées doivent posséder une information de prélèvement servi avec les mêmes valeurs, à l'exception du montant qui peut différer d'une ligne à l'autre.</regleFonctionnelle>
+ <regleTechnique>Les informations de prélèvement doivent être identiques sur chaque ligne du titre ORMC.</regleTechnique>
+ <libelle>Les informations de prélèvement doivent être identiques sur chaque ligne du titre ORMC.</libelle>
+ <severity>BLOQUANT</severity>
+ <severityHelios></severityHelios>
+ </message>
+ <message id="MREC46" ctrlId="REC20">
+ <regleFonctionnelle>Si la pièce est de type ORMC (balise TypPce = ORMC), si au moins une ligne de titre rattachée possède des références bancaires présentes et si la nature de prélèvement est égale à "Fichier remis aux organismes bancaires par le Trésor", alors toutes les lignes de titres rattachées doivent posséder des références bancaires servies avec les mêmes valeurs.</regleFonctionnelle>
+ <regleTechnique>Les références bancaires doivent être identiques sur chaque ligne du titre ORMC.</regleTechnique>
+ <libelle>Les références bancaires doivent être identiques sur chaque ligne du titre ORMC.</libelle>
+ <severity>BLOQUANT</severity>
+ <severityHelios></severityHelios>
+ </message>
+
<!-- Contrôles de tiers -->
--- /dev/null
+/*
+ * Copyright
+ * 2012 axYus - www.axyus.com
+ * 2012 axYus - contact@axyus.com
+ *
+ * This file is part of XEMELIOS.
+ *
+ * XEMELIOS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package fr.gouv.finances.cp.xemelios.controls.pesv2.rec;
+
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.TreeSet;
+
+import nu.xom.Document;
+import nu.xom.Nodes;
+
+import org.apache.log4j.Logger;
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+
+import fr.gouv.finances.cp.xemelios.controls.pesv2.ControlUtilsPes;
+import fr.gouv.finances.dgfip.xemelios.controls.core.Anomalie;
+import fr.gouv.finances.dgfip.xemelios.controls.core.ControlReturn;
+import fr.gouv.finances.dgfip.xemelios.controls.core.MessagesProvider;
+
+/**
+ *
+ * @author jp.tessier
+ */
+public class REC20 extends ControlUtilsPes {
+
+ public static final String CTRL_ID = REC20.class.getSimpleName();
+ public static final String TYPE_BORD_ORMC = "06";
+ public static final String TYPE_PIECE_ORMC = "15";
+ private final static Logger logger = Logger.getLogger(REC20.class);
+ private final ArrayList<ControlReturn> anos = new ArrayList<ControlReturn>();
+ private MessagesProvider messageAnomalie;
+ private int compteurAnos = 0;
+
+ public static final String CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT = CHEMIN_LIGNE_DE_PIECE_RECETTE + "BlocLignePiece/InfoPrelevement/";
+ public static final String CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_NATPREL = CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT + "NatPrel/";
+ public static final String CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_PERPREL = CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT + "PerPrel/";
+ public static final String CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_DATEPREL = CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT + "DtePrel/";
+
+ public static final String CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA = CHEMIN_LIGNE_DE_PIECE_RECETTE + "BlocLignePiece/InfoPrelevementSEPA/";
+ public static final String CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA_NATPREL = CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA + "NatPrel/";
+ public static final String CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA_PERPREL = CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA + "PerPrel/";
+ public static final String CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA_DATEPREL = CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA + "DtePrel/";
+
+ public static final String CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA_SEQUENCE = CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA + "SequencePres/";
+ public static final String CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA_DATE_SIGN = CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA + "DateSignMandat/";
+ public static final String CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA_REF_UNI_MDT = CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA + "RefUniMdt/";
+ public static final String CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA_LIB_PREL = CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA + "LibPrel/";
+ public static final String CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA_ANCIEN_RUM = CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA + "AncienRUM/";
+ public static final String CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA_ANCIEN_ICS = CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA + "AncienICS/";
+ public static final String CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA_ANCIEN_CREANCIER = CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA + "AncienTiersCreancier/";
+ public static final String CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA_ANCIENNE_BANQUE = CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA + "AncienneBanque/";
+ public static final String CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA_ANCIEN_IBAN = CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA + "AncienIBAN/";
+ public static final String CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA_TIT_COMPTE_DIFF = CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA + "TitCpteDiff/";
+
+ /**
+ * Path de la balise mettant fin à l'analyse du flux
+ */
+ /**
+ * Variables contenant les valeurs nécessaires à ce contrôle
+ */
+ private String typeBordereauNodeId, typPceNodeId, natPceNodeId = "";
+ private String exercice, idBordereau, typeBordereau, idPce, typPce, natPce = null;
+ private String typeTiers = "", nomTiers = "", prenomTiers = "", dateNaissanceTiers = "", cpTiers = "", villeTiers = "";
+ private String natPrel = "", perPrel = "", datePrel = "";
+ private String natPrelSEPA = "", perPrelSEPA = "", datePrelSEPA = "", sequencePresSEPA = "", dateSignMandatSEPA = "", refUniMdtSEPA = "", libPrelSEPA = "", ancienRUMSEPA = "", ancienICSSEPA = "", ancienTiersCreancierSEPA = "", ancienneBanqueSEPA = "", ancienIBANSEPA = "", titCpteDiffSEPA = "";
+ private String codeEtab = "", codeGuic = "", idCpte = "", cleRib = "", bic ="", iban = "";
+ private String tiersNodeId = "";
+ private String infoNodeId = "";
+ private String cpteBancaireNodeId = "";
+ private Document tableRef;
+ private Nodes nodesListe;
+ private TreeSet<String> typesPiece = new TreeSet<String>();
+ private ArrayList<DebiteurPrincipal> debiteurs = new ArrayList<DebiteurPrincipal>();
+ private ArrayList<InfoPrelevement> infosPrelevement = new ArrayList<InfoPrelevement>();
+ private ArrayList<InfoPrelevementSEPA> infosPrelevementSEPA = new ArrayList<InfoPrelevementSEPA>();
+ private ArrayList<CompteBancaireRib> comptesRib = new ArrayList<CompteBancaireRib>();
+ private ArrayList<CompteBancaireBicIban> comptesBicIban = new ArrayList<CompteBancaireBicIban>();
+
+
+ /**
+ * Path des informations recherchées
+ */
+ private static final String ON_RETURN_ANOMALIE = CHEMIN_BORDEREAU_RECETTE;
+
+ @Override
+ public void startDocument() throws SAXException {
+
+ logger.info(CTRL_ID + " : Début du controle.");
+ this.messageAnomalie = this.getMessagesProvider();
+ this.setStatusControle(ETAT_EXECUTE_NON_APPLICABLE);
+
+ /*
+ * Recherche de la liste des triplets autorisés
+ */
+ this.tableRef = this.getTableReference(CTRL_ID);
+ if (this.tableRef == null) {
+ logger.error(new StringBuffer("La/Les table(s) de référence du controle").append(CTRL_ID).append("n'est pas définie").toString());
+ throw new SAXException();
+ }
+ }
+
+ @Override
+ public void startElement(final String uri, final String localName, final String qName, final Attributes atts, final String xpath) throws SAXException {
+ /*
+ * Réinitialisation du tableaux d'anomalie
+ */
+ if (xpath.endsWith(ON_RETURN_ANOMALIE)) {
+ this.anos.clear();
+ }
+
+ /*
+ * Mémorisation des informations nécessaires aux contrôles
+ */
+
+ // Verifier si les 2 balises sont obligatoires dans le schéma
+
+ if (xpath.endsWith(CHEMIN_PIECE_RECETTE_IDPIECE)) {
+ this.idPce = atts.getValue("V");
+ }
+ if (xpath.endsWith(CHEMIN_PIECE_RECETTE_TYPPCE)) {
+ this.typPce = atts.getValue("V");
+ typesPiece.add(this.typPce);
+ this.typPceNodeId = atts.getValue("ano:node-id");
+ }
+ if (xpath.endsWith(CHEMIN_PIECE_RECETTE_NATPCE)) {
+ this.natPce = atts.getValue("V");
+ this.natPceNodeId = atts.getValue("ano:node-id");
+ }
+ if (xpath.endsWith(CHEMIN_BLOCBORDEREAU_EXER)) {
+ this.exercice = atts.getValue("V");
+ }
+ if (xpath.endsWith(CHEMIN_BLOCBORDEREAU_IDBORD)) {
+ this.idBordereau = atts.getValue("V");
+ }
+ if (xpath.endsWith(CHEMIN_BLOCBORDEREAU_TYPBORD)) {
+ this.typeBordereau = atts.getValue("V");
+ this.typeBordereauNodeId = atts.getValue("ano:node-id");
+ }
+
+ if (xpath.endsWith(CHEMIN_TIERS)) {
+ this.tiersNodeId = atts.getValue("ano:node-id");
+ }
+ if (xpath.endsWith(CHEMIN_TIERS_ADRESSE_CP)) {
+ this.cpTiers = atts.getValue("V");
+ }
+ if (xpath.endsWith(CHEMIN_TIERS_ADRESSE_VILLE)) {
+ this.villeTiers = atts.getValue("V");
+ }
+ if (xpath.endsWith(CHEMIN_TIERS_INFO_TYPE)) {
+ this.typeTiers = atts.getValue("V");
+ }
+ if (xpath.endsWith(CHEMIN_TIERS_INFO_NOM)) {
+ this.nomTiers = atts.getValue("V");
+ }
+ if (xpath.endsWith(CHEMIN_TIERS_INFO_PRENOM)) {
+ this.prenomTiers = atts.getValue("V");
+ }
+ if (xpath.endsWith(CHEMIN_TIERS_INFO_DATE_NAISSANCE)) {
+ this.dateNaissanceTiers = atts.getValue("V");
+ }
+
+ if (xpath.contains(CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT)) {
+ this.infoNodeId = atts.getValue("ano:node-id");
+ if (xpath.endsWith(CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_NATPREL)) {
+ this.natPrel = atts.getValue("V");
+ }
+ if (xpath.endsWith(CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_PERPREL)) {
+ this.perPrel = atts.getValue("V");
+ }
+ if (xpath.endsWith(CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_DATEPREL)) {
+ this.datePrel = atts.getValue("V");
+ }
+ }
+ if (xpath.contains(CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA)) {
+ this.infoNodeId = atts.getValue("ano:node-id");
+
+ if (xpath.endsWith(CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA_NATPREL)) {
+ this.natPrelSEPA = atts.getValue("V");
+ }
+ if (xpath.endsWith(CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA_PERPREL)) {
+ this.perPrelSEPA = atts.getValue("V");
+ }
+ if (xpath.endsWith(CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA_DATEPREL)) {
+ this.datePrelSEPA = atts.getValue("V");
+ }
+
+
+ if (xpath.endsWith(CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA_SEQUENCE)) {
+ this.sequencePresSEPA = atts.getValue("V");
+ }
+ if (xpath.endsWith(CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA_DATE_SIGN)) {
+ this.dateSignMandatSEPA = atts.getValue("V");
+ }
+ if (xpath.endsWith(CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA_REF_UNI_MDT)) {
+ this.refUniMdtSEPA = atts.getValue("V");
+ }
+ if (xpath.endsWith(CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA_LIB_PREL)) {
+ this.libPrelSEPA = atts.getValue("V");
+ }
+ if (xpath.endsWith(CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA_ANCIEN_RUM)) {
+ this.ancienRUMSEPA = atts.getValue("V");
+ }
+ if (xpath.endsWith(CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA_ANCIEN_ICS)) {
+ this.ancienICSSEPA = atts.getValue("V");
+ }
+ if (xpath.endsWith(CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA_ANCIEN_CREANCIER)) {
+ this.ancienTiersCreancierSEPA = atts.getValue("V");
+ }
+ if (xpath.endsWith(CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA_ANCIENNE_BANQUE)) {
+ this.ancienneBanqueSEPA = atts.getValue("V");
+ }
+ if (xpath.endsWith(CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA_ANCIEN_IBAN)) {
+ this.ancienIBANSEPA = atts.getValue("V");
+ }
+ if (xpath.endsWith(CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA_TIT_COMPTE_DIFF)) {
+ this.titCpteDiffSEPA = atts.getValue("V");
+ }
+ }
+
+ if (xpath.contains(CHEMIN_TIERS_COMPTE)) {
+ this.cpteBancaireNodeId = atts.getValue("ano:node-id");
+
+ if(xpath.endsWith(CHEMIN_TIERS_COMPTE_CODEETAB)){
+ this.codeEtab = atts.getValue("V");
+ }
+ if(xpath.endsWith(CHEMIN_TIERS_COMPTE_CODEGUIC)){
+ this.codeGuic = atts.getValue("V");
+ }
+ if(xpath.endsWith(CHEMIN_TIERS_COMPTE_IDCPTE)){
+ this.idCpte = atts.getValue("V");
+ }
+ if(xpath.endsWith(CHEMIN_TIERS_COMPTE_CLERIB)){
+ this.cleRib = atts.getValue("V");
+ }
+ if(xpath.endsWith(CHEMIN_TIERS_COMPTE_BIC)){
+ this.bic = atts.getValue("V");
+ }
+ if(xpath.endsWith(CHEMIN_TIERS_COMPTE_IBAN)){
+ this.iban = atts.getValue("V");
+ }
+ }
+
+ }
+
+ @Override
+ public ArrayList<ControlReturn> endElement(final String uri, final String localName, final String qName, final String xpath) throws SAXException {
+ if(xpath.endsWith(CHEMIN_TIERS)){
+ if("01".equals(this.typeTiers)){ // On ne stocke que les débiteurs principaux (01)
+ debiteurs.add(new DebiteurPrincipal(this.typeTiers, this.nomTiers, this.prenomTiers, this.dateNaissanceTiers, this.cpTiers, this.villeTiers, this.tiersNodeId));
+ }
+ this.typeTiers = ""; this.nomTiers = ""; this.prenomTiers = ""; this.dateNaissanceTiers = ""; this.cpTiers = ""; this.villeTiers = "";
+
+ if(!"".equals(this.bic) && !"".equals(this.iban)){
+ comptesBicIban.add(new CompteBancaireBicIban(this.bic, this.iban, this.cpteBancaireNodeId));
+ } else if(!"".equals(this.codeEtab) && !"".equals(this.codeGuic)) {
+ comptesRib.add(new CompteBancaireRib(this.codeEtab, this.codeGuic, this.idCpte, this.cleRib, this.cpteBancaireNodeId));
+ }
+ this.codeEtab = ""; this.codeGuic = ""; this.idCpte = ""; this.cleRib = ""; this.bic = ""; this.iban = "";
+ }
+
+ if(xpath.endsWith(CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT)){
+ infosPrelevement.add(new InfoPrelevement(this.natPrel, this.perPrel, this.datePrel, this.infoNodeId));
+ this.natPrel = ""; this.perPrel = ""; this.datePrel = "";
+ }
+ if(xpath.endsWith(CHEMIN_LIGNE_DE_PIECE_RECETTE_INFOPRELEVEMENT_SEPA)){
+ infosPrelevementSEPA.add(new InfoPrelevementSEPA(this.natPrelSEPA, this.perPrelSEPA, this.datePrelSEPA, this.sequencePresSEPA, this.dateSignMandatSEPA, this.refUniMdtSEPA, this.libPrelSEPA, this.ancienRUMSEPA, this.ancienICSSEPA, this.ancienTiersCreancierSEPA, this.ancienneBanqueSEPA, this.ancienIBANSEPA, this.titCpteDiffSEPA, this.infoNodeId));
+ this.natPrelSEPA = ""; this.perPrelSEPA = ""; this.datePrelSEPA = ""; this.sequencePresSEPA = ""; this.dateSignMandatSEPA = ""; this.refUniMdtSEPA = ""; this.libPrelSEPA = ""; this.ancienRUMSEPA = ""; this.ancienICSSEPA = ""; this.ancienTiersCreancierSEPA = ""; this.ancienneBanqueSEPA = ""; this.ancienIBANSEPA = ""; this.titCpteDiffSEPA = ""; this.infoNodeId = "";
+ }
+
+ if (xpath.endsWith(CHEMIN_PIECE_RECETTE)) {
+ // MREC43
+ // Si la pièce est de type ORMC (balise TypPce = 15), alors le bordereau est de type ORMC (balise TypBord = 06).
+ if(TYPE_PIECE_ORMC.equals(this.typPce) && !TYPE_BORD_ORMC.equals(this.typeBordereau)){
+ final Anomalie ano = this.addPesAnomalie(this, this.getDocumentModel(), this.messageAnomalie, false, this.exercice, this.typeBordereau, this.idBordereau, "MREC43", null, PIECE_ELEMENT_ID, this.idPce);
+ ano.addNode(this.typPceNodeId);
+ this.anos.add(ano);
+ }
+ // MREC44
+ // Si la pièce est de type ORMC (balise TypPce = 15), alors toutes les lignes de titres rattachées doivent avoir pour type tiers « débiteur principal » (01),
+ // le même nom, le même prénom, la même date de naissance si celle-ci est servie, le même code postal et la même ville.
+ String tiersEnErreur = isDebiteursPrincipauxAreIdentiques();
+ if(TYPE_PIECE_ORMC.equals(this.typPce) && tiersEnErreur != null){
+ final Anomalie ano = this.addPesAnomalie(this, this.getDocumentModel(), this.messageAnomalie, false, this.exercice, this.typeBordereau, this.idBordereau, "MREC44", null, PIECE_ELEMENT_ID, this.idPce);
+ ano.addNode(tiersEnErreur);
+ this.anos.add(ano);
+ }
+ debiteurs.clear();
+
+ // MREC45
+ /* Si la pièce est de type ORMC (balise TypPce = 15), et si au moins une ligne de titre rattachée possède un "BlocInfoPrélèvement" ou "BlocInfoPrélèvementSEPA" servi,
+ * alors toutes les lignes de titres rattachées doivent posséder un "BlocInfoPrélèvement" ou "BlocInfoPrélèvementSEPA" servi avec les mêmes valeurs,
+ * à l\92exception du montant qui peut différer d\92une ligne à l\92autre.
+ */
+ String infoPrelEnErreur = isInfosPrelevementAreIdentiques();
+ String infoPrelSepaEnErreur = isInfosPrelevementSepaAreIdentiques();
+ if(TYPE_PIECE_ORMC.equals(this.typPce) && (infoPrelEnErreur != null || infoPrelSepaEnErreur != null)){
+ final Anomalie ano = this.addPesAnomalie(this, this.getDocumentModel(), this.messageAnomalie, false, this.exercice, this.typeBordereau, this.idBordereau, "MREC45", null, PIECE_ELEMENT_ID, this.idPce);
+ ano.addNode(infoPrelEnErreur==null?infoPrelSepaEnErreur:infoPrelEnErreur);
+ this.anos.add(ano);
+ }
+ infosPrelevement.clear();infosPrelevementSEPA.clear();
+
+ // MREC46
+ /* Si la pièce est de type ORMC (balise TypPce = ORMC), si au moins une ligne de titre rattachée possède des BIC et IBAN présents
+ * et si la nature de prélèvement est égale à "Fichier remis aux organismes bancaires par le Trésor", alors toutes les lignes de titres rattachées doivent posséder
+ * des BIC et IBAN servis avec les mêmes valeurs.
+ */
+ String ribEnErreur = isRibAreIdentiques();
+ String bicIbanEnErreur = isBicIbanAreIdentiques();
+ if(TYPE_PIECE_ORMC.equals(this.typPce) && (ribEnErreur != null || bicIbanEnErreur != null)){
+ final Anomalie ano = this.addPesAnomalie(this, this.getDocumentModel(), this.messageAnomalie, false, this.exercice, this.typeBordereau, this.idBordereau, "MREC46", null, PIECE_ELEMENT_ID, this.idPce);
+ ano.addNode(ribEnErreur==null?bicIbanEnErreur:ribEnErreur);
+ this.anos.add(ano);
+ }
+ comptesRib.clear();comptesBicIban.clear();
+
+ }
+
+ if(xpath.endsWith(CHEMIN_BORDEREAU_RECETTE)){
+ // MREC42
+ // Si le bordereau est de type ORMC (balise TypBord = 06 ), alors toutes les pièces incluses dans le bordereau doivent être de type ORMC (balise TypPiece = 15).
+ if(TYPE_BORD_ORMC.equals(this.typeBordereau) && !(typesPiece.size() == 1 && this.typesPiece.contains(TYPE_PIECE_ORMC))){
+ final Anomalie ano = this.addPesAnomalie(this, this.getDocumentModel(), this.messageAnomalie, false, this.exercice, this.typeBordereau, this.idBordereau, "MREC42", null, BORDEREAU_ELEMENT_ID, null);
+ ano.addNode(this.typeBordereauNodeId);
+ this.anos.add(ano);
+ }
+ this.typesPiece.clear();
+ }
+
+ if (xpath.endsWith(ON_RETURN_ANOMALIE)) {
+ // ANOMALIE
+ if (this.getStatusControle() == ETAT_EXECUTE_NON_APPLICABLE && TYPE_BORD_ORMC.equals(this.typeBordereau)) {
+ this.setStatusControle(ETAT_EXECUTE_SANS_ANOS);
+ }
+
+ this.compteurAnos += this.anos.size();
+ return this.anos;
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public void setDocumentLocator(final Locator locator) {
+ }
+
+ @Override
+ public void endDocument() throws SAXException {
+ logger.info(new StringBuilder(CTRL_ID).append(" : Fin du controle. ").append(this.compteurAnos).append(" anomalie(s). Statut : ").append(vStatuts[this.getStatusControle()]));
+ }
+
+ @Override
+ public void startPrefixMapping(final String prefix, final String uri, final String xpath) throws SAXException {
+ }
+
+ @Override
+ public void endPrefixMapping(final String prefix, final String xpath) throws SAXException {
+ }
+
+ @Override
+ public void characters(final char[] ch, final int start, final int length, final String xpath) throws SAXException {
+ }
+
+ @Override
+ public void ignorableWhitespace(final char[] ch, final int start, final int length, final String xpath) throws SAXException {
+ }
+
+ @Override
+ public void processingInstruction(final String target, final String data, final String xpath) throws SAXException {
+ }
+
+ @Override
+ public void skippedEntity(final String name, final String xpath) throws SAXException {
+ }
+
+ @Override
+ public void setParameters(final Hashtable<String, Object> params) {
+ }
+
+ @Override
+ public String getControlId() {
+ return CTRL_ID;
+ }
+
+ private String isDebiteursPrincipauxAreIdentiques(){
+ String retour = null;
+ DebiteurPrincipal lastDebiteur = null;
+ for(DebiteurPrincipal debiteur : debiteurs){
+ if(lastDebiteur!=null && debiteur.compareTo(lastDebiteur) != 0){
+ retour = debiteur.tiersNodeId;
+ break;
+ }
+ lastDebiteur=debiteur;
+ }
+ return retour;
+ }
+
+ private String isInfosPrelevementAreIdentiques(){
+ String retour = null;
+ InfoPrelevement lastInfoPrel = null;
+ for(InfoPrelevement infoPrel : infosPrelevement){
+ if(lastInfoPrel!=null && infoPrel.compareTo(lastInfoPrel) != 0){
+ retour = infoPrel.infoNodeId;
+ break;
+ }
+ lastInfoPrel=infoPrel;
+ }
+ return retour;
+ }
+
+ private String isInfosPrelevementSepaAreIdentiques(){
+ String retour = null;
+ InfoPrelevementSEPA lastInfoPrel = null;
+ for(InfoPrelevementSEPA infoPrel : infosPrelevementSEPA){
+ if(lastInfoPrel!=null && infoPrel.compareTo(lastInfoPrel) != 0){
+ retour = infoPrel.infoNodeId;
+ break;
+ }
+ lastInfoPrel=infoPrel;
+ }
+ return retour;
+ }
+
+ private String isRibAreIdentiques(){
+ String retour = null;
+ CompteBancaireRib lastRib = null;
+ for(CompteBancaireRib compte : comptesRib){
+ if(lastRib!=null && compte.compareTo(lastRib) != 0){
+ retour = compte.compteNodeId;
+ break;
+ }
+ lastRib=compte;
+ }
+ return retour;
+ }
+
+ private String isBicIbanAreIdentiques(){
+ String retour = null;
+ CompteBancaireBicIban lastRib = null;
+ for(CompteBancaireBicIban compte : comptesBicIban){
+ if(lastRib!=null && compte.compareTo(lastRib) != 0){
+ retour = compte.compteNodeId;
+ break;
+ }
+ lastRib=compte;
+ }
+ return retour;
+ }
+
+ private class DebiteurPrincipal implements Comparable<DebiteurPrincipal> {
+ private String typeTiers;
+ private String nom;
+ private String prenom;
+ private String dateNaissance;
+ private String cp;
+ private String ville;
+ private String tiersNodeId;
+
+ public DebiteurPrincipal(String typeTiers, String nom, String prenom, String dateNaissance, String cp, String ville, String tiersNodeId) {
+ this.typeTiers = typeTiers;
+ this.nom = nom;
+ this.prenom = prenom;
+ this.dateNaissance = dateNaissance;
+ this.cp = cp;
+ this.ville = ville;
+ this.tiersNodeId = tiersNodeId;
+ }
+
+ @Override
+ public int compareTo(DebiteurPrincipal o) {
+ if(this.nom.equals(o.nom) && this.prenom.equals(o.prenom) && this.dateNaissance.equals(o.dateNaissance) && this.cp.equals(o.cp) && this.ville.equals(o.ville)){
+ return 0;
+ }
+ return -1;
+ }
+
+
+ }
+
+ private class InfoPrelevement implements Comparable<InfoPrelevement> {
+ private String natPrel = "", perPrel = "", datePrel = "";
+ private String infoNodeId;
+
+ public InfoPrelevement(String natPrel, String perPrel, String datePrel, String infoNodeId) {
+ this.natPrel = natPrel;
+ this.perPrel = perPrel;
+ this.datePrel = datePrel;
+ this.infoNodeId = infoNodeId;
+ }
+
+ @Override
+ public int compareTo(InfoPrelevement o) {
+ if(this.natPrel.equals(o.natPrel) && this.perPrel.equals(o.perPrel) && this.datePrel.equals(o.datePrel)){
+ return 0;
+ }
+ return -1;
+ }
+ }
+
+ private class InfoPrelevementSEPA implements Comparable<InfoPrelevementSEPA> {
+ private String natPrel = "", perPrel = "", datePrel = "", sequencePresSEPA = "", dateSignMandatSEPA = "", refUniMdtSEPA = "";
+ private String libPrelSEPA = "", ancienRUMSEPA = "", ancienICSSEPA = "", ancienTiersCreancierSEPA = "", ancienneBanqueSEPA = "", ancienIBANSEPA = "", titCpteDiffSEPA = "";
+ private String infoNodeId = "";
+
+ public InfoPrelevementSEPA(String natPrel, String perPrel, String datePrelSEPA, String sequencePresSEPA, String dateSignMandatSEPA, String refUniMdtSEPA, String libPrelSEPA, String ancienRUMSEPA, String ancienICSSEPA, String ancienTiersCreancierSEPA, String ancienneBanqueSEPA, String ancienIBANSEPA, String titCpteDiffSEPA, String infoNodeId) {
+ this.natPrel = natPrel;
+ this.perPrel = perPrel;
+ this.datePrel = datePrelSEPA;
+ this.sequencePresSEPA = sequencePresSEPA;
+ this.dateSignMandatSEPA = dateSignMandatSEPA;
+ this.refUniMdtSEPA = refUniMdtSEPA;
+ this.libPrelSEPA = libPrelSEPA;
+ this.ancienRUMSEPA = ancienRUMSEPA;
+ this.ancienICSSEPA = ancienICSSEPA;
+ this.ancienTiersCreancierSEPA = ancienTiersCreancierSEPA;
+ this.ancienneBanqueSEPA = ancienneBanqueSEPA;
+ this.ancienIBANSEPA = ancienIBANSEPA;
+ this.titCpteDiffSEPA = titCpteDiffSEPA;
+ this.infoNodeId = infoNodeId;
+ }
+
+ @Override
+ public int compareTo(InfoPrelevementSEPA o) {
+ if(this.natPrel.equals(o.natPrel) && this.perPrel.equals(o.perPrel) && this.datePrel.equals(o.datePrel)
+ && this.sequencePresSEPA.equals(o.sequencePresSEPA)
+ && this.dateSignMandatSEPA.equals(o.dateSignMandatSEPA)
+ && this.refUniMdtSEPA.equals(o.refUniMdtSEPA)
+ && this.libPrelSEPA.equals(o.libPrelSEPA)
+ && this.ancienRUMSEPA.equals(o.ancienRUMSEPA)
+ && this.ancienICSSEPA.equals(o.ancienICSSEPA)
+ && this.ancienTiersCreancierSEPA.equals(o.ancienTiersCreancierSEPA)
+ && this.ancienneBanqueSEPA.equals(o.ancienneBanqueSEPA)
+ && this.ancienIBANSEPA.equals(o.ancienIBANSEPA)
+ && this.titCpteDiffSEPA.equals(o.titCpteDiffSEPA)){
+ return 0;
+ }
+ return -1;
+ }
+ }
+
+ private class CompteBancaireRib implements Comparable<CompteBancaireRib> {
+ private String codeEtab = "", codeGuic = "", idCpte = "", cleRib = "";
+ private String compteNodeId;
+
+ public CompteBancaireRib(String codeEtab, String codeGuic, String idCpte, String cleRib, String compteNodeId) {
+ this.codeEtab = codeEtab;
+ this.codeGuic = codeGuic;
+ this.idCpte = idCpte;
+ this.cleRib = cleRib;
+ this.compteNodeId = compteNodeId;
+ }
+
+ @Override
+ public int compareTo(CompteBancaireRib o) {
+ if(this.codeEtab.equals(o.codeEtab) && this.codeGuic.equals(o.codeGuic) && this.idCpte.equals(o.idCpte) && this.cleRib.equals(o.cleRib)){
+ return 0;
+ }
+ return -1;
+ }
+ }
+
+ private class CompteBancaireBicIban implements Comparable<CompteBancaireBicIban> {
+ private String bic = "", iban = "";
+ private String compteNodeId;
+
+ public CompteBancaireBicIban(String bic, String iban, String compteNodeId) {
+ this.bic = bic;
+ this.iban = iban;
+ this.compteNodeId = compteNodeId;
+ }
+
+ @Override
+ public int compareTo(CompteBancaireBicIban o) {
+ if(this.bic.equals(o.bic) && this.iban.equals(o.iban)){
+ return 0;
+ }
+ return -1;
+ }
+ }
+
+}