'use strict';
define(function() {
  var facturationCtrl = function(
    $scope,
    AncAppFactory,
    FeatureTypeFactory,
    $filter,
    QueryFactory,
    gaDomUtils,
    $timeout,
    FeatureAttachmentFactory,
    $rootScope,
    gaJsUtils,
    dolibarrFactory,
    AncAppSearchFactory,
    $q,
    OmegaFactory,
    ngDialog
  ) {
    $scope.facturationMode = AncAppFactory.appCfg.main.properties.dolibarr
      .active
      ? 'dolibarr'
      : 'simple';
    var dateReference = AncAppFactory.appCfg.main.periodesCfg.dateReference;
    var controleFTI = FeatureTypeFactory.getFeatureByNameAndDatastore(
      AncAppFactory.appCfg.main.datastore,
      'kis_anc_dossier_controle'
    );
    var demandeurFTI = FeatureTypeFactory.getFeatureByNameAndDatastore(
      AncAppFactory.appCfg.main.datastore,
      'kis_anc_demandeur'
    );
    var vidangeFormulaireFTI = FeatureTypeFactory.getFeatureByNameAndDatastore(
      AncAppFactory.appCfg.main.datastore,
      'kis_anc_vidange_formulaire'
    );

    $scope.facturationTabs = [
      {
        title: 'Génération',
        content:
          'js/XG/widgets/ancapp/main/views/facturation/facturation.generation.html',
      },
    ];

    $scope.numberSelected = 100;

    $scope.facturationSpeciale = false;
    if (
      AncAppFactory.appCfg.main.properties.dolibarr.facturationTierce.active
    ) {
      $scope.facturationSpeciale =
        AncAppFactory.appCfg.main.properties.dolibarr.facturationTierce.interface.type;
    }

    // la synthese est dans kis
    if ($scope.facturationMode == 'simple') {
      $scope.facturationTabs.push({
        title: 'Synthèse de facturation',
        content:
          'js/XG/widgets/ancapp/main/views/facturation/facturation.synthese.html',
      });
      // la synthese est dans dolibarr, on verifie cependant la connexion
    } else {
      $scope.dolibarrCfg = dolibarrFactory.cfg;
      $scope.facturationTabs.push({
        title: 'Exports Multi-Facturation',
        content:
          'js/XG/widgets/ancapp/main/views/facturation/facturation.exports.multifac.html',
      });

      $scope.$watch('facturationTabs.activeTab', function(newval) {
        if (angular.isDefined(newval) && newval == 1)
          $scope.getlisteexportsjvs();
      });

      dolibarrFactory.setDolibarrConnectionCfg(
        AncAppFactory.appCfg.main.properties.dolibarr
      );
      dolibarrFactory.setDolibarrConnection(1);
    }
    $scope.facturationTabs.activeTab = 0;

    $scope.goToDolibarr = function() {
      if (gaJsUtils.checkNestedProperty('cfg.params.url', dolibarrFactory)) {
        window.open(dolibarrFactory.cfg.params.url);
      } else {
        alert("L'adresse n'est pas configurée");
      }
    };

    /***************************************************************************
     * GENERATION
     **************************************************************************/

    $scope.controlesFti = angular.copy(
      FeatureTypeFactory.getFeatureByNameAndDatastore(
        AncAppFactory.appCfg.main.datastore,
        'kis_anc_dossier_controle'
      )
    );
    $scope.controleAttributes = [];
    $scope.controlesFti.attributes.forEach(function(att) {
      if (
        ~[
          'type',
          'avis',
          'agent',
          'date_saisie_controle',
          'date_passage',
          'date_avis',
        ].indexOf(att.name)
      ) {
        $scope.controleAttributes.push(att);
      }
    });

    $scope.periodesCfg = angular.copy(AncAppFactory.appCfg.main.periodesCfg);
    $scope.controleCfgList = angular.copy(
      AncAppFactory.appCfg.main.controleCfg
    );

    $scope.generation_filter = {
      where: '',
      nom_periode: '',
      prefixe: '',
      date_generation: new Date(),
      date_echeance: new Date(),
    };
    $timeout(function() {
      // condition de pre replissage
      const configExists = AncAppFactory.appCfg.main &&
                            AncAppFactory.appCfg.main.properties &&
                            AncAppFactory.appCfg.main.properties.dolibarr &&
                            AncAppFactory.appCfg.main.properties.dolibarr.facturationRechercheConfig &&
                            Object.keys(AncAppFactory.appCfg.main.properties.dolibarr.facturationRechercheConfig);
      // pré-remplissage des valeurs sauvegardées 
      // ou par défaut si aucune sauvegarde
      if (!configExists) {
        $scope.generation_filter = {
          where: '',
          nom_periode: '',
          prefixe: '',
          date_generation: new Date(),
          date_echeance: new Date(),
          debut: $filter('date')(
            moment().subtract(3, 'months'),
            'yyyy-MM-ddTHH:mm:ss.sssZ'
          ).toDate(), // dev
          fin: $filter('date')(
            moment().add(1, 'day'),
            'yyyy-MM-ddTHH:mm:ss.sssZ'
          ).toDate(), // add 1 jour pour prendre en compte les factures du jour
        }
      }else{
        $scope.generation_filter = {
          where: '',
          nom_periode: AncAppFactory.appCfg.main.properties.dolibarr.facturationRechercheConfig.nomPeriode,
          prefixe:  AncAppFactory.appCfg.main.properties.dolibarr.facturationRechercheConfig.prefixe,
          date_generation: AncAppFactory.appCfg.main.properties.dolibarr.facturationRechercheConfig.dateGeneration,
          date_echeance: AncAppFactory.appCfg.main.properties.dolibarr.facturationRechercheConfig.dateEcheance,
          debut: AncAppFactory.appCfg.main.properties.dolibarr.facturationRechercheConfig.debut,
          fin: AncAppFactory.appCfg.main.properties.dolibarr.facturationRechercheConfig.fin
        };
      }
      
    }, 100);

    /**
     * le filtre complet pour recuperation des controles avant génération
     *
     * @param infos
     * @returns {string}
     */
    var getFullControleFilter = function() {
      var where =
        AncAppFactory.appCfg.main.periodesCfg.dateReference +
        ' ' +
        ">= '" +
        $scope.generation_filter.debut +
        "' AND " +
        AncAppFactory.appCfg.main.periodesCfg.dateReference +
        ' ' +
        "<= '" +
        $scope.generation_filter.fin +
        "'" +
        "AND statut_facture = 'aucune'" +
        "AND etat = 'clos'";

      return where;
    };

    /**
     * refreshListe pour facturation
     */
    $scope.refreshListePourGenerationFacture = function() {
      if (
        !angular.isDefined($scope.generation_filter.debut) ||
        !angular.isDefined($scope.generation_filter.fin)
      ) {
        return;
      }

      gaDomUtils.showGlobalLoader();
      QueryFactory.data($scope.controlesFti.uid, getFullControleFilter()).then(
        function(res) {
          var counts = {};
          for (var i in res.data.features) {
            var feat = res.data.features[i];
            if (!angular.isDefined(counts[feat.properties.type]))
              counts[feat.properties.type] = [];
            counts[feat.properties.type].push(feat);
          }

          $scope.controleCfgList.forEach(function(c, idx) {
            $scope.controleCfgList[idx].picked = true;
            $scope.controleCfgList[idx].nbconcernes = 0;
            $scope.controleCfgList[idx].concernes = [];

            if (angular.isDefined(counts[c.type])) {
              $scope.controleCfgList[idx].nbconcernes = counts[c.type].length;
              $scope.controleCfgList[idx].concernes = counts[c.type];
            }
          });
          gaDomUtils.hideGlobalLoader();
        },
        function() {
          require('toastr').error(
            'Erreur lors de la récupérations des controles facturables.'
          );
          gaDomUtils.hideGlobalLoader();
        }
      );
    };

    // @TODO move it to gaJsUtils and do the same for elasticEditRequest
    function getDeepObjectByKeyValue(obj, key, value) {
      var result = null;
      if (obj instanceof Array) {
        for (var i = 0; i < obj.length; i++) {
          result = getDeepObjectByKeyValue(obj[i], key, value);
          if (result) break;
        }
      } else {
        for (var prop in obj) {
          if (prop == key) {
            if (obj[prop] == value) {
              return obj;
            }
          }
          if (obj[prop] instanceof Object || obj[prop] instanceof Array)
            result = getDeepObjectByKeyValue(obj[prop], key, value);
          if (result) break;
        }
      }
      return result;
    }

    $scope.displayListeFacturable = 'cache';

    var fakeCtrlFti = {};
    var toRetrieveCtrls = AncAppFactory.appCfg.main.controleCfg.map(function(
      x
    ) {
      return AncAppFactory.getBuildedFakeCtrlReponseFtiForElasticSearch(x.type);
    });

    $q.all(toRetrieveCtrls).then(function(x, i) {
      x.map(function(i, index) {
        fakeCtrlFti[AncAppFactory.appCfg.main.controleCfg[index].type] = i;
      });
      $scope.fakeCtrlFtiBuilt = true;
    });

    var resetAFacturer = function() {
      $scope.tmpShowRes = {};
      $scope.aFacturer = {};
      $scope.aFacturerLength = { total: 0 };
    };

    $scope.generationFiltersLocked = false;
    $scope.unlockGenerationFilters = function() {
      $scope.generationFiltersLocked = false;
      $scope.displayListeFacturable = 'cache';
    };
    /**
     * refreshListePourGenerationFacturev2
     */
    $scope.refreshListePourGenerationFacturev2 = function() {
      // validité des champs nom periode et prefixe
      var regexp = /^[a-zA-Z0-9-_]+$/;

      if (
        $scope.generation_filter.nom_periode != '' &&
        $scope.generation_filter.nom_periode.search(regexp) == -1
      ) {
        require('toastr').error(
          'Le nom de la période ne peut contenir que des chiffres, lettres non accentuées, - et _.'
        );
        return;
      }
      if (
        $scope.generation_filter.prefixe != '' &&
        $scope.generation_filter.prefixe.search(regexp) == -1
      ) {
        require('toastr').error(
          'Le nom de la période ne peut contenir que des chiffres, lettres non accentuées, - et _.'
        );
        return;
      }

      $scope.generationFiltersLocked = true;

      $scope.displayListeFacturable = 'cache';
      $scope.elementsFacturationEligible = [];

      if (
        !angular.isDefined($scope.generation_filter.debut) ||
        !angular.isDefined($scope.generation_filter.fin)
      ) {
        return;
      }
      //sauvegarde du paramétrage de recherche de facturation
      AncAppFactory.appCfg.main.properties.dolibarr.facturationRechercheConfig = 
        {
        nomPeriode : $scope.generation_filter.nom_periode,
        prefixe : $scope.generation_filter.prefixe,
        debut : $scope.generation_filter.debut,
        fin : $scope.generation_filter.fin,
        dateGeneration : $scope.generation_filter.date_generation,
        dateEcheance : $scope.generation_filter.date_echeance
        };
      AncAppFactory.updateAppCfg();
      gaDomUtils.showGlobalLoader();

      $timeout(function() {
        // Récupération des PERIODES qui chevauchent les dates renseignées
        var periodesEligibles = $scope.periodesCfg.periodes
          .filter(function(x) {
            return !(
              moment($scope.generation_filter.debut) >= moment(x.fin) ||
              moment($scope.generation_filter.fin) <= moment(x.debut)
            );
          })
          .map(function(z) {
            return z.key;
          });

        var elementsFacturationEligible = $scope.periodesCfg.templates.filter(
          function(x) {
            return periodesEligibles.indexOf(x.periode) != -1 && x.elasticQuery;
          }
        );

        // alimentation des objets reduits dans la requete pour qu'elle soient
        // plus courte
        for (var i in elementsFacturationEligible) {
          // @TODO pour les vidanges on doit recupere le json correspondant
          // mais ce n'est pas encore fait dans la recherche, donc en
          // attendant on triche et on passe FO0
          if (angular.isDefined(elementsFacturationEligible[i].vidanges)) {
            firstType = 'FO0';
          } else {
            var firstType = false;
            for (var j in elementsFacturationEligible[i].controles) {
              if (
                !firstType &&
                elementsFacturationEligible[i].controles[j].selected
              ) {
                firstType = j;
              }
            }
          }

          if (firstType == false) {
            require('toastr').error(
              'Erreur dans un modèle de facturation qui ne correspond à aucun contrôle.'
            );
            gaDomUtils.hideGlobalLoader();
            return;
          }

          var mRequest = AncAppSearchFactory.unPackRequest(
            elementsFacturationEligible[i],
            AncAppFactory.appCfg.main.datastore,
            fakeCtrlFti[firstType]
          );

          // met a jour l'alias de la relation avec le json
          mRequest.elasticQuery.relations[0].filters[1].alias =
            fakeCtrlFti[firstType].alias;
          mRequest = resolveFiliere(mRequest);
          resolveControleFti(mRequest);
        }

        $scope.displayListeFacturable = 'pour_facturation';
        if (!$scope.elementsFacturationEligible.length) return;

        resetAFacturer();

        // ancien mode desactive, a recabler si necessaire
        if ($scope.facturationMode == 'simple') {
          // voir dans git
        } else {
          for (var i in $scope.elementsFacturationEligible) {
            var guid = gaJsUtils.guid();
            var efe = $scope.elementsFacturationEligible[i];

            var estFacturationVidanges = angular.isDefined(efe.vidanges);

            if (estFacturationVidanges) {
              var attributDateDeRequete = vidangeFormulaireFTI.attributes.filter(
                function(x) {
                  // attention : dans le cadre de la vidange, la date de
                  // controle s'apelle bien date_controle (et non pas
                  // date_passage comme pour les controles)
                  var toSearch =
                    dateReference == 'date_passage'
                      ? 'date_controle'
                      : dateReference;
                  return x.name == toSearch;
                }
              )[0];
            } else {
              var attributDateDeRequete = controleFTI.attributes.filter(
                function(x) {
                  return x.name == dateReference;
                }
              )[0];
            }

            console.log('dateReference : ' + dateReference);
            if (!angular.isDefined(attributDateDeRequete)) {
              console.log('ERREUR : attribut date de la requete inconnu');
            }

            efe.labelDebiteur = 'Propriétaire';
            if (efe.debiteur == 'locataire') efe.labelDebiteur = 'Occupant';
            if (efe.debiteur == 'demandeur') efe.labelDebiteur = 'Demandeur';

            // demande GEB, tout le monde s'apelle Débiteur
            efe.labelDebiteurOriginal = angular.copy(efe.labelDebiteur);
            efe.labelDebiteur = 'Débiteur';

            efe.tmp = { filterId: guid };
            efe.picked = false;
            efe.facturationid = 'factu_' + i;

            $scope.aFacturer[efe.facturationid] = {};
            $scope.aFacturerLength[efe.facturationid] = 0;

            // recuperation des criteres date de debut et de fin
            $scope.debutCrit = getDeepObjectByKeyValue(
              efe.elasticQuery,
              'guid',
              'factu_date_debut'
            );
            $scope.finCrit = getDeepObjectByKeyValue(
              efe.elasticQuery,
              'guid',
              'factu_date_fin'
            );

            var periodeCorrespondante = $scope.periodesCfg.periodes.filter(
              function(x) {
                return x.key == efe.periode;
              }
            )[0];

            // force le champ date selon la configuration de l'appli (date
            // controle, date saisie, date avis)
            [$scope.debutCrit, $scope.finCrit].forEach(function(crit, index) {
              crit.attr = attributDateDeRequete;
              crit.att = attributDateDeRequete.alias;
              crit.name = attributDateDeRequete.name;

              // doit etre borne par les filtres + la periode de facturation
              var dateRef;
              if (index == 0) {
                dateRef =
                  moment($scope.generation_filter.debut) >
                  moment(periodeCorrespondante.debut)
                    ? $scope.generation_filter.debut
                    : periodeCorrespondante.debut;
              } else {
                dateRef =
                  moment($scope.generation_filter.fin) <
                  moment(periodeCorrespondante.fin)
                    ? $scope.generation_filter.fin
                    : periodeCorrespondante.fin;
              }

              crit.value = $filter('date')(dateRef, 'yyyy-MM-dd');
            });
          }

          gaDomUtils.hideGlobalLoader();
        }
      }, 300);
    };

    /**
     * searchForFacturable
     */
    $scope.searchForFacturable = function(elemfactu) {
      $scope.aFacturer[elemfactu.facturationid] = {};
      elemfactu.toggle_all = false;

      gaDomUtils.showGlobalLoader();
      $scope.currentFactuFilterId = elemfactu.tmp.filterId;

      $timeout(function() {
        if (!elemfactu.controles || !Object.keys(elemfactu.controles).length) {
          return $rootScope.$broadcast('elastic_LoadAndExecuteRequest', {
            request: elemfactu.elasticQuery,
            filterId: elemfactu.tmp.filterId,
          });
        }
        let promises = [];
        Object.keys(elemfactu.controles)
          .filter(controlName => elemfactu.controles[controlName].selected)
          .forEach(controlName => {
            if (elemfactu.controles[controlName].selected) {
              promises.push(
                AncAppFactory.getBuildedFakeCtrlReponseFtiForElasticSearch(
                  controlName
                )
              );
            }
          });
        $q.all(promises).then(fakeCtrlFtis => {
          const intersectedAttributes = {};
          const attrs = {};
          fakeCtrlFtis.forEach((control, index) => {
            (control.attributes || []).forEach(attribute => {
              intersectedAttributes[attribute.name] =
                intersectedAttributes[attribute.name] || [];
              if (intersectedAttributes[attribute.name].indexOf(index) === -1) {
                intersectedAttributes[attribute.name].push(index);
                attrs[attribute.name] = attribute;
              }
            });
          });
          (elemfactu.elasticQuery.jointure || []).forEach(jointure => {
            if (
              jointure &&
              jointure.fti &&
              jointure.fti.uid === 'kis_anc_dossier_controle'
            ) {
              jointure.fti = Object.assign(jointure.fti, {
                attributes: jointure.fti.attributes
                  .map(attribute =>
                    Object.assign(attribute, {
                      category: 'Metadonees',
                      prefixedAlias: attribute.alias,
                    })
                  )
                  .concat(
                    Object.keys(attrs)
                      .filter(
                        attr =>
                          intersectedAttributes[attr].length ===
                          fakeCtrlFtis.length
                      )
                      .map(attr => attrs[attr])
                  ),
              });
              jointure.fti.attributesaliases = jointure.fti.attributes.map(
                attribute => attribute.alias
              );
            }
          });
          return $rootScope.$broadcast('elastic_LoadAndExecuteRequest', {
            request: elemfactu.elasticQuery,
            filterId: elemfactu.tmp.filterId,
            annualisation: elemfactu.parameters && elemfactu.parameters.annualisation 
            && elemfactu.parameters.annualisation.active ? elemfactu.parameters.annualisation : false ,
          });
        });
      }, 100);
    };

    // resultat d'une requete elastic, on controle si des infos sont manquantes
    // qui empechent de facturer
    $scope.$on('resultelastic', function(
      event,
      q,
      t,
      r,
      filterId,
      queryResult
    ) {
      gaDomUtils.hideGlobalLoader();

      if (angular.isDefined(filterId)) {
        $scope.filter_id = filterId;
        var elementFactu = $scope.elementsFacturationEligible.filter(function(
          x
        ) {
          return x.tmp.filterId == filterId;
        });

        // correspondance avec l'element facturable
        if (elementFactu.length) {
          var toCheck = elementFactu[0];

          // affiche le detail
          $scope.tmpShowRes[toCheck.facturationid] = true;
          SortQueryResult(queryResult,$scope.generation_filter.type_filter);
          toCheck.tmp.res = queryResult;

          if (!toCheck.tmp.res.features.length) return;

          // recuperation de l'historique des personnes associées à l'élément
          // de facturation
          var promise,
            idsDossiers = gaJsUtils
              .arrayUnique(
                toCheck.tmp.res.features.map(function(x) {
                  return x.properties.ref_dossier.replace(
                    'kis_anc_dossier.',
                    ''
                  );
                })
              )
              .join('-'),
            idDemandeurs = gaJsUtils
              .arrayUnique(
                toCheck.tmp.res.features.map(function(x) {
                  return x.properties.id_demandeur;
                })
              )
              .filter(function(x) {
                return x !== null;
              })
              .join(',');

          if (toCheck.debiteur == 'proprietaire')
            promise = AncAppFactory.gethistopersonnesdossier(
              'proprietaires',
              idsDossiers
            );
          if (toCheck.debiteur == 'locataire')
            promise = AncAppFactory.gethistopersonnesdossier(
              'locataires',
              idsDossiers
            );

          if (toCheck.debiteur == 'demandeur') {
            if (idDemandeurs == '') idDemandeurs = -1;
            // recuperation du demandeur depuis le controle
            promise = QueryFactory.get(demandeurFTI.uid, idDemandeurs);
          }

          promise.then(function(res) {
            toCheck.tmp.nbErreurs = 0;

            // demandeur
            if (toCheck.debiteur == 'demandeur') {
              toCheck.tmp.res.features.forEach(function(ft) {
                console.log(ft)
                if (ft.properties.id_demandeur == null) {
                  ft.canCheck = false;
                  ft.err = {
                    debiteur:
                      "Aucun demandeur n'est renseigné dans le contrôle",
                  };
                  toCheck.tmp.nbErreurs++;
                } else {
                  res.data.features.forEach(function(f) {
                    var nom, prenom, civilite;
                    if (ft.properties.id_demandeur == f.id) {
                      ft.canCheck = true;

                      civilite =
                        angular.isDefined(f.properties.civilite) &&
                        f.properties.civilite != null
                          ? f.properties.civilite
                          : '';
                      prenom =
                        angular.isDefined(f.properties.prenom) &&
                        f.properties.prenom != null
                          ? f.properties.prenom
                          : '';
                      nom =
                        angular.isDefined(f.properties.nom) &&
                        f.properties.nom != null
                          ? f.properties.nom
                          : '';

                      ft.libDebiteurControle =
                        civilite + ' ' + prenom + ' ' + nom;
                      ft.libDebiteurDossier = ft.libDebiteurControle;
                      ft.debiteurFinal = f;
                    }
                  });
                }

                ft.dateDeReference = ft.originalProperties['date_passage'];
              });

              // proprietaire/locataire
            } else {
              // reindexation des reponses par ref_dossier
              var histoPersonnes = {};

              res.data.forEach(function(x) {
                if (
                  !angular.isDefined(
                    histoPersonnes[x.feature.properties.ref_dossier]
                  )
                )
                  histoPersonnes[x.feature.properties.ref_dossier] = [];
                histoPersonnes[x.feature.properties.ref_dossier].push(x);
              });

              // vidange ou controle
              var estFacturationVidanges = angular.isDefined(toCheck.vidanges);

              // verification des données débiteur pour chaque controle
              toCheck.tmp.res.features.forEach(function(ft) {
                var debiteurOk = false;

                // verification du libelle de la personne présent dans le
                // controle
                if (!estFacturationVidanges) {
                  var nom, prenom, civilite;
                  switch (toCheck.debiteur) {
                    case 'proprietaire':
                      nom =
                        ft.originalProperties[
                          'info_generales.proprietaire.nom'
                        ];
                      prenom =
                        ft.originalProperties[
                          'info_generales.proprietaire.prenom'
                        ];
                      civilite =
                        ft.originalProperties[
                          'info_generales.proprietaire.civilite'
                        ];
                      break;
                    case 'locataire':
                      nom =
                        ft.originalProperties['info_generales.locataire.nom'];
                      prenom =
                        ft.originalProperties[
                          'info_generales.locataire.prenom'
                        ];
                      civilite =
                        ft.originalProperties[
                          'info_generales.locataire.civilite'
                        ];
                      break;
                  }

                  civilite =
                    angular.isDefined(civilite) && civilite != null
                      ? civilite
                      : '';
                  prenom =
                    angular.isDefined(prenom) && prenom != null ? prenom : '';
                  nom = angular.isDefined(nom) && nom != null ? nom : '';

                  ft.libDebiteurControle = civilite + ' ' + prenom + ' ' + nom;
                  if (ft.libDebiteurControle.trim() == '')
                    ft.libDebiteurControle = 'non renseigné';

                  // quel etait la personne connue sur ce dossier à cette date
                  // var key = (dateReference == '' &&
                  // ft.originalProperties.type == 'FO0') ? 'date_demande' :
                  // dateReference;
                  // toujours la date_passage
                  ft.dateDeReference = ft.originalProperties['date_passage'];

                  var refDossier = ft.originalProperties.ref_dossier;
                } else {
                  var key = 'date_controle';
                  ft.dateDeReference = ft.properties[key];
                  var refDossier = ft.properties.ref_dossier;
                }

                var vraiDebiteur = false,
                  vraiDebiteurFeature = false,
                  nbPayeursEquivalentRedevance = 0;

                var needToCheckPayeur = false;

                // recuperation de la personne présente à cette date
                if (angular.isDefined(histoPersonnes[refDossier])) {
                  if (toCheck.debiteur === 'proprietaire' ||
                      toCheck.debiteur === 'locataire' ||
                      histoPersonnes[refDossier].length > 1
                  ) {
                    needToCheckPayeur = true;
                  }

                  histoPersonnes[refDossier].forEach(function(histo) {
                    var h = histo.feature.properties;
                    if (!toCheck.parameters.factIsRedevable) {
                      if (
                        h.debut &&
                        (!needToCheckPayeur || h.est_redevable == true)
                      ) {
                        var tsControle = parseInt(
                          moment(ft.dateDeReference).format('x')
                        );
                        var debut = parseInt(
                          moment(h.debut).startOf('day').format('x')
                        );

                        if (
                          tsControle >= debut &&
                          (h.courant == true || tsControle <= h.fin)
                        ) {
                          if (h.est_redevable)
                            nbPayeursEquivalentRedevance += 1;

                          vraiDebiteur = histo.info_personne;
                          vraiDebiteurFeature = histo.featurePersonne;
                        }
                      }
                    } else if (h.courant && h.est_redevable) {
                      nbPayeursEquivalentRedevance += 1;
                      vraiDebiteur = histo.info_personne;
                      vraiDebiteurFeature = histo.featurePersonne;
                    }                    
                  });
                }

                if (!angular.isDefined(ft.err)) ft.err = {};
                var errDebiteur = [];
                let errDebiteurExtraInfo = '';

                if (needToCheckPayeur && nbPayeursEquivalentRedevance != 1) {
                  errDebiteur.push(
                    nbPayeursEquivalentRedevance == 0
                      ? "Aucun payeur de l'équivalent redevance à cette date (" +
                          moment(ft.dateDeReference).format('DD-MM-YYYY') +
                          ')'
                      : "Plusieurs payeurs de l'équivalent redevance à cette date (" +
                          moment(ft.dateDeReference).format('DD-MM-YYYY') +
                          ')'
                  );
                } else {
                   if (vraiDebiteur) {
                     if ($scope.facturationSpeciale == 'omega' &&
                        ft.properties.id_point_conso_omega != null) {
                          debiteurOk = 
                            vraiDebiteur.nom != null &&
                            vraiDebiteur.nom.trim() != '';
                     } else {
                      let cpIsOk = false;
                      if (vraiDebiteurFeature.properties){
                        const cpIsDefined = 
                          vraiDebiteurFeature.properties.adresse_cp != null &&
                          vraiDebiteurFeature.properties.adresse_cp.trim() != '';
                        cpIsOk = cpIsDefined || vraiDebiteur.pays != 'France';
                      }
                      debiteurOk =
                      vraiDebiteur.nom != null &&
                      vraiDebiteur.nom.trim() != '' &&
                      vraiDebiteur.prenom != null &&
                      vraiDebiteur.prenom.trim() != '' &&
                      vraiDebiteur.civilite != null &&
                      vraiDebiteur.civilite.trim() != '' &&
                      vraiDebiteur.rue != null &&
                      vraiDebiteur.rue.trim() != '' &&
                      vraiDebiteur.pays != null &&
                      vraiDebiteur.pays.trim() != '' &&
                      cpIsOk;
                     }

                     if (!debiteurOk) {
                       let somethingIsMissing = false;
                       if (
                         vraiDebiteur.nom == null ||
                         vraiDebiteur.nom.trim() == ''
                       ) {
                         errDebiteur.push('Nom manquant');
                         somethingIsMissing = true;
                       }
                       if (
                         !(
                           $scope.facturationSpeciale == 'omega' &&
                           ft.properties.id_point_conso_omega
                         ) &&
                         (vraiDebiteur.prenom == null ||
                           vraiDebiteur.prenom.trim() == '')
                       ) {
                         errDebiteur.push('Prénom manquant');
                         somethingIsMissing = true;
                       }
                       if (
                         !(
                           $scope.facturationSpeciale == 'omega' &&
                           ft.properties.id_point_conso_omega
                         ) &&
                         (vraiDebiteur.civilite == null ||
                           vraiDebiteur.civilite.trim() == '')
                       ) {
                         errDebiteur.push('Civilité manquante');
                         somethingIsMissing = true;
                       }
                       if (
                        !(
                          $scope.facturationSpeciale == 'omega' &&
                          ft.properties.id_point_conso_omega
                        ) &&
                        (vraiDebiteur.rue == null ||
                          vraiDebiteur.rue.trim() == '')
                      ) {
                        errDebiteur.push('Rue manquante');
                        somethingIsMissing = true;
                      }
                      if (
                        !(
                          $scope.facturationSpeciale == 'omega' &&
                          ft.properties.id_point_conso_omega
                        ) &&
                        (vraiDebiteurFeature.properties.adresse_cp == null ||
                          vraiDebiteurFeature.properties.adresse_cp.trim() == '') &&
                        (vraiDebiteur.pays == 'France')
                      ) {
                        errDebiteur.push('Code postal manquant');
                        somethingIsMissing = true;
                      }
                      if (
                        !(
                          $scope.facturationSpeciale == 'omega' &&
                          ft.properties.id_point_conso_omega
                        ) &&
                        (vraiDebiteur.pays == null ||
                          vraiDebiteur.pays.trim() == '')
                      ) {
                        errDebiteur.push('Pays manquant');
                        somethingIsMissing = true;
                      }

                       // info sur le debiteur concerne pour lequel il manque qqch
                       if (somethingIsMissing) {
                         if (vraiDebiteur.prenom != null)
                           errDebiteurExtraInfo += ` ${vraiDebiteur.prenom}`;
                         if (vraiDebiteur.nom != null)
                           errDebiteurExtraInfo += ` ${vraiDebiteur.nom}`;
                         errDebiteurExtraInfo = `(${errDebiteurExtraInfo.trim()})`;
                       }
                     } else {
                       ft.libDebiteurDossier =
                         vraiDebiteur.civilite +
                         ' ' +
                         vraiDebiteur.prenom +
                         ' ' +
                         vraiDebiteur.nom;
                     }
                   } else {
                     errDebiteur.push(
                       'Aucune personne dans les informations du dossier à cette date (' +
                         moment(ft.dateDeReference).format('DD-MM-YYYY') +
                         ')'
                     );
                   }
                }

                ft.err.debiteur =
                  errDebiteur.join(', ') + ' ' + errDebiteurExtraInfo;
                ft.debiteurFinal = vraiDebiteurFeature;
                ft.canCheck = debiteurOk;

                if ($scope.facturationSpeciale == 'omega') {
                  console.log(ft.properties)
                  if (ft.properties.id_point_conso_omega == null) {
                    ft.canCheck = false;
                    ft.err.debiteur =
                      "Il manque un identifiant, merci d'aller sur le dossier et de rafraîchir le point de consommation Omega";
                  }
                }

                if (!ft.canCheck) {
                  toCheck.tmp.nbErreurs = toCheck.tmp.nbErreurs
                    ? toCheck.tmp.nbErreurs + 1
                    : 1;
                }
              });
            }

            // sauf si locataires, on a deja
            // si demandeurs refdossier n'est pas defined
            // juillet 2019, on recupere aussi les infos du locataire
            AncAppFactory.gethistopersonnesdossier(
              'locataires',
              idsDossiers
            ).then(function(res) {
              toCheck.tmp.res.features.forEach(function(ft) {
                var histoPersonnes = {};

                res.data.forEach(function(x) {
                  if (
                    !angular.isDefined(
                      histoPersonnes[x.feature.properties.ref_dossier]
                    )
                  )
                    histoPersonnes[x.feature.properties.ref_dossier] = [];
                  histoPersonnes[x.feature.properties.ref_dossier].push(x);
                });

                var infosOccupant = false;
                if (ft.originalProperties)
                  var refDossier = ft.originalProperties.ref_dossier;
                else if (ft.properties) refDossier = ft.properties.ref_dossier;
                if (refDossier) {
                  if (angular.isDefined(histoPersonnes[refDossier])) {
                    histoPersonnes[refDossier].forEach(function(histo) {
                      var h = histo.feature.properties;
                      if (h.debut) {
                        var tsControle = parseInt(
                          moment(ft.dateDeReference).format('x')
                        );
                        var debut = parseInt(
                          moment(h.debut)
                            .startOf('day')
                            .format('x')
                        );
                        if (
                          tsControle >= debut &&
                          (h.courant == true || tsControle <= h.fin)
                        ) {
                          infosOccupant = histo.featurePersonne;
                        }
                      }
                    });
                  }
                  ft.occupantFinal = infosOccupant;
                }
              });
            });
            if (
              toCheck.parameters &&
              toCheck.parameters.annualisation &&
              toCheck.parameters.annualisation.active
            ) {
              AncAppFactory.getControleFacturableAvecFacturationAnnuelle().then(
                (res) => {
                  toCheck.tmp.res.features.forEach((ft, i) => {
                    if (
                      ft.properties.statut_facture &&
                      ft.properties.statut_facture ===
                        'FACTURE_ANNUELLE_EN_COURS'
                    ) {
                      if (Array.isArray(res.data) && res.data.length > 0) {
                        const actualYear = new Date().getFullYear();
                        const controleEcheances = res.data.filter(
                          (controle) => controle.referenceControle === ft.id
                        );
                        if (controleEcheances && controleEcheances.length > 0) {
                          const controleEcheanceActuelle =
                            controleEcheances.find(
                              (controleEcheance) =>
                                controleEcheance.anneeEcheance === actualYear.toString()
                            );
                          if (controleEcheanceActuelle) {
                            ft.properties.echeanceEncours = true;
                          } else {
                            ft.cannotCheckEcheance = true;
                            toCheck.tmp.nbErreurs++;
                            ft.err.echeance =
                              "Ce contrôle est en cours de facturation annuelle, mais la redevance de l'année en cours est déjà facturée";
                          }
                        } else {
                          ft.cannotCheckEcheance = true;
                          toCheck.tmp.nbErreurs++;
                          ft.err.echeance =
                            'Ce contrôle est en cours de facturation annuelle, mais on lui trouve aucune écheance dans la table des factures annuelles ';
                        }
                      } else {
                        ft.cannotCheckEcheance = true;
                        toCheck.tmp.nbErreurs++;
                        ft.err.echeance =
                         'Ce contrôle est en cours de facturation annuelle, mais on lui trouve aucune écheance dans la table des factures annuelles ';
                      }
                    }
                  });
                }
              );
            }           
          });
        }
      }
    });

    $scope.$on('updateDebiteurEvent', function(event, report_id){
      $scope.updateDebiteur(report_id);
    });

    $scope.updateDebiteur = function(report_id) {
      if (angular.isDefined($scope.filter_id)) {
        var elementFactu = $scope.elementsFacturationEligible.filter(function(
          x
        ) {
          return x.tmp.filterId == $scope.filter_id;
        });
        var report = elementFactu[0].tmp.res.features.find(function (
          x
        ){
          return x.properties.ref_dossier == report_id;
        });
      }
      
      var toCheck = elementFactu[0];
      if(report.canCheck) toCheck.tmp.nbErreurs++;
      // recuperation de l'historique des personnes associées à l'élément
      // de facturation
      var promise,
        idsDossiers = gaJsUtils
          .arrayUnique(
            toCheck.tmp.res.features.map(function(x) {
              return x.properties.ref_dossier.replace(
                'kis_anc_dossier.',
                ''
              );
            })
          )
          .join('-'),
        idDemandeurs = gaJsUtils
          .arrayUnique(
            toCheck.tmp.res.features.map(function(x) {
              return x.properties.id_demandeur;
            })
          )
          .filter(function(x) {
            return x !== null;
          })
          .join(',');

      if (toCheck.debiteur == 'proprietaire')
        promise = AncAppFactory.gethistopersonnesdossier(
          'proprietaires',
          idsDossiers
        );
      if (toCheck.debiteur == 'locataire')
        promise = AncAppFactory.gethistopersonnesdossier(
          'locataires',
          idsDossiers
        );

      if (toCheck.debiteur == 'demandeur') {
        if (idDemandeurs == '') idDemandeurs = -1;
        // recuperation du demandeur depuis le controle
        promise = QueryFactory.get(demandeurFTI.uid, idDemandeurs);
      }

      promise.then(function(res) {
        // demandeur
        if (toCheck.debiteur == 'demandeur') {
          // toCheck.tmp.res.features.forEach(function(ft) {
          if (report.properties.id_demandeur == null) {
            report.canCheck = false;
            report.err = {
              debiteur:
                "Aucun demandeur n'est renseigné dans le contrôle",
            };
            toCheck.tmp.nbErreurs++;
          } else {
            res.data.features.forEach(function(f) {
              var nom, prenom, civilite;
              if (report.properties.id_demandeur == f.id) {
                report.canCheck = true;

                civilite =
                  angular.isDefined(f.properties.civilite) &&
                  f.properties.civilite != null
                    ? f.properties.civilite
                    : '';
                prenom =
                  angular.isDefined(f.properties.prenom) &&
                  f.properties.prenom != null
                    ? f.properties.prenom
                    : '';
                nom =
                  angular.isDefined(f.properties.nom) &&
                  f.properties.nom != null
                    ? f.properties.nom
                    : '';

                report.libDebiteurControle =
                  civilite + ' ' + prenom + ' ' + nom;
                report.libDebiteurDossier = report.libDebiteurControle;
                report.debiteurFinal = f;
              }
            });
          }

          report.dateDeReference = report.originalProperties['date_passage'];
          // });

          // proprietaire/locataire
        } else {
          // reindexation des reponses par ref_dossier
          var histoPersonnes = {};

          res.data.forEach(function(x) {
            if (
              !angular.isDefined(
                histoPersonnes[x.feature.properties.ref_dossier]
              )
            )
              histoPersonnes[x.feature.properties.ref_dossier] = [];
            histoPersonnes[x.feature.properties.ref_dossier].push(x);
          });

          // vidange ou controle
          var estFacturationVidanges = angular.isDefined(toCheck.vidanges);

          // verification des données débiteur pour chaque controle
          // toCheck.tmp.res.features.forEach(function(ft) {
            var debiteurOk = false;

            // verification du libelle de la personne présent dans le
            // controle
            if (!estFacturationVidanges) {
              var nom, prenom, civilite;
              switch (toCheck.debiteur) {
                case 'proprietaire':
                  nom =
                    report.originalProperties[
                      'info_generales.proprietaire.nom'
                    ];
                  prenom =
                    report.originalProperties[
                      'info_generales.proprietaire.prenom'
                    ];
                  civilite =
                    report.originalProperties[
                      'info_generales.proprietaire.civilite'
                    ];
                  break;
                case 'locataire':
                  nom =
                    report.originalProperties['info_generales.locataire.nom'];
                  prenom =
                    report.originalProperties[
                      'info_generales.locataire.prenom'
                    ];
                  civilite =
                    report.originalProperties[
                      'info_generales.locataire.civilite'
                    ];
                  break;
              }

              civilite =
                angular.isDefined(civilite) && civilite != null
                  ? civilite
                  : '';
              prenom =
                angular.isDefined(prenom) && prenom != null ? prenom : '';
              nom = angular.isDefined(nom) && nom != null ? nom : '';

              report.libDebiteurControle = civilite + ' ' + prenom + ' ' + nom;
              if (report.libDebiteurControle.trim() == '')
                report.libDebiteurControle = 'non renseigné';

              // quel etait la personne connue sur ce dossier à cette date
              // var key = (dateReference == '' &&
              // report.originalProperties.type == 'FO0') ? 'date_demande' :
              // dateReference;
              // toujours la date_passage
              report.dateDeReference = report.originalProperties['date_passage'];

              var refDossier = report.originalProperties.ref_dossier;
            } else {
              var key = 'date_controle';
              report.dateDeReference = report.properties[key];
              var refDossier = report.properties.ref_dossier;
            }

            var vraiDebiteur = false,
              vraiDebiteurFeature = false,
              nbPayeursEquivalentRedevance = 0;

            var needToCheckPayeur = false;

            // recuperation de la personne présente à cette date
            if (angular.isDefined(histoPersonnes[refDossier])) {
              if (toCheck.debiteur === 'proprietaire' ||
                  toCheck.debiteur === 'locataire' ||
                  histoPersonnes[refDossier].length > 1
              ) {
                needToCheckPayeur = true;
              }

              histoPersonnes[refDossier].forEach(function(histo) {
                var h = histo.feature.properties;
                if (!toCheck.parameters.factIsRedevable) {
                  if (
                    h.debut &&
                    (!needToCheckPayeur || h.est_redevable == true)
                  ) {
                    var tsControle = parseInt(
                      moment(report.dateDeReference).format('x')
                    );
                    var debut = parseInt(
                      moment(h.debut).startOf('day').format('x')
                    );

                    if (
                      tsControle >= debut &&
                      (h.courant == true || tsControle <= h.fin)
                    ) {
                      if (h.est_redevable)
                        nbPayeursEquivalentRedevance += 1;

                      vraiDebiteur = histo.info_personne;
                      vraiDebiteurFeature = histo.featurePersonne;
                    }
                  }
                } else if (h.courant && h.est_redevable) {
                  nbPayeursEquivalentRedevance += 1;
                  vraiDebiteur = histo.info_personne;
                  vraiDebiteurFeature = histo.featurePersonne;
                }                    
              });
            }

            if (!angular.isDefined(report.err)) report.err = {};
            var errDebiteur = [];
            let errDebiteurExtraInfo = '';

            if (needToCheckPayeur && nbPayeursEquivalentRedevance != 1) {
              errDebiteur.push(
                nbPayeursEquivalentRedevance == 0
                  ? "Aucun payeur de l'équivalent redevance à cette date (" +
                      moment(report.dateDeReference).format('DD-MM-YYYY') +
                      ')'
                  : "Plusieurs payeurs de l'équivalent redevance à cette date (" +
                      moment(report.dateDeReference).format('DD-MM-YYYY') +
                      ')'
              );
            } else {
               if (vraiDebiteur) {
                 if ($scope.facturationSpeciale == 'omega' &&
                    report.properties.id_point_conso_omega != null) {
                      debiteurOk = 
                        vraiDebiteur.nom != null &&
                        vraiDebiteur.nom.trim() != '';
                 } else {
                  let cpIsOk = false;
                  if (vraiDebiteurFeature.properties){
                    const cpIsDefined = 
                      vraiDebiteurFeature.properties.adresse_cp != null &&
                      vraiDebiteurFeature.properties.adresse_cp.trim() != '';
                    cpIsOk = cpIsDefined || vraiDebiteur.pays != 'France';
                  }
                  debiteurOk =
                  vraiDebiteur.nom != null &&
                  vraiDebiteur.nom.trim() != '' &&
                  vraiDebiteur.prenom != null &&
                  vraiDebiteur.prenom.trim() != '' &&
                  vraiDebiteur.civilite != null &&
                  vraiDebiteur.civilite.trim() != '' &&
                  vraiDebiteur.rue != null &&
                  vraiDebiteur.rue.trim() != '' &&
                  vraiDebiteur.pays != null &&
                  vraiDebiteur.pays.trim() != '' &&
                  cpIsOk;
                 }

                 if (!debiteurOk) {
                   let somethingIsMissing = false;
                   if (
                     vraiDebiteur.nom == null ||
                     vraiDebiteur.nom.trim() == ''
                   ) {
                     errDebiteur.push('Nom manquant');
                     somethingIsMissing = true;
                   }
                   if (
                     !(
                       $scope.facturationSpeciale == 'omega' &&
                       report.properties.id_point_conso_omega
                     ) &&
                     (vraiDebiteur.prenom == null ||
                       vraiDebiteur.prenom.trim() == '')
                   ) {
                     errDebiteur.push('Prénom manquant');
                     somethingIsMissing = true;
                   }
                   if (
                     !(
                       $scope.facturationSpeciale == 'omega' &&
                       report.properties.id_point_conso_omega
                     ) &&
                     (vraiDebiteur.civilite == null ||
                       vraiDebiteur.civilite.trim() == '')
                   ) {
                     errDebiteur.push('Civilité manquante');
                     somethingIsMissing = true;
                   }
                   if (
                    !(
                      $scope.facturationSpeciale == 'omega' &&
                      report.properties.id_point_conso_omega
                    ) &&
                    (vraiDebiteur.rue == null ||
                      vraiDebiteur.rue.trim() == '')
                  ) {
                    errDebiteur.push('Rue manquante');
                    somethingIsMissing = true;
                  }
                  if (
                    !(
                      $scope.facturationSpeciale == 'omega' &&
                      report.properties.id_point_conso_omega
                    ) &&
                    (vraiDebiteurFeature.properties.adresse_cp == null ||
                      vraiDebiteurFeature.properties.adresse_cp.trim() == '') &&
                    (vraiDebiteur.pays == 'France')
                  ) {
                    errDebiteur.push('Code postal manquant');
                    somethingIsMissing = true;
                  }
                  if (
                    !(
                      $scope.facturationSpeciale == 'omega' &&
                      report.properties.id_point_conso_omega
                    ) &&
                    (vraiDebiteur.pays == null ||
                      vraiDebiteur.pays.trim() == '')
                  ) {
                    errDebiteur.push('Pays manquant');
                    somethingIsMissing = true;
                  }

                   // info sur le debiteur concerne pour lequel il manque qqch
                   if (somethingIsMissing) {
                     if (vraiDebiteur.prenom != null)
                       errDebiteurExtraInfo += ` ${vraiDebiteur.prenom}`;
                     if (vraiDebiteur.nom != null)
                       errDebiteurExtraInfo += ` ${vraiDebiteur.nom}`;
                     errDebiteurExtraInfo = `(${errDebiteurExtraInfo.trim()})`;
                   }
                 } else {
                   report.libDebiteurDossier =
                     vraiDebiteur.civilite +
                     ' ' +
                     vraiDebiteur.prenom +
                     ' ' +
                     vraiDebiteur.nom;
                 }
               } else {
                 errDebiteur.push(
                   'Aucune personne dans les informations du dossier à cette date (' +
                     moment(report.dateDeReference).format('DD-MM-YYYY') +
                     ')'
                 );
               }
            }

            report.err.debiteur =
              errDebiteur.join(', ') + ' ' + errDebiteurExtraInfo;
            report.debiteurFinal = vraiDebiteurFeature;
            report.canCheck = debiteurOk;

            if ($scope.facturationSpeciale == 'omega') {
              console.log(report.properties)
              if (report.properties.id_point_conso_omega == null) {
                report.canCheck = false;
                report.err.debiteur =
                  "Il manque un identifiant, merci d'aller sur le dossier et de rafraîchir le point de consommation Omega";
              }
            }
        }

        // sauf si locataires, on a deja
        // si demandeurs refdossier n'est pas defined
        // juillet 2019, on recupere aussi les infos du locataire
        AncAppFactory.gethistopersonnesdossier(
          'locataires',
          idsDossiers
        ).then(function(res) {
            var histoPersonnes = {};

            res.data.forEach(function(x) {
              if (
                !angular.isDefined(
                  histoPersonnes[x.feature.properties.ref_dossier]
                )
              )
                histoPersonnes[x.feature.properties.ref_dossier] = [];
              histoPersonnes[x.feature.properties.ref_dossier].push(x);
            });

            var infosOccupant = false;
            if (report.originalProperties)
              var refDossier = report.originalProperties.ref_dossier;
            else if (report.properties) refDossier = report.properties.ref_dossier;
            if (refDossier) {
              if (angular.isDefined(histoPersonnes[refDossier])) {
                histoPersonnes[refDossier].forEach(function(histo) {
                  var h = histo.feature.properties;
                  if (h.debut) {
                    var tsControle = parseInt(
                      moment(report.dateDeReference).format('x')
                    );
                    var debut = parseInt(
                      moment(h.debut)
                        .startOf('day')
                        .format('x')
                    );
                    if (
                      tsControle >= debut &&
                      (h.courant == true || tsControle <= h.fin)
                    ) {
                      infosOccupant = histo.featurePersonne;
                    }
                  }
                });
              }
              report.occupantFinal = infosOccupant;
            }
        });
        if (
          toCheck.parameters &&
          toCheck.parameters.annualisation &&
          toCheck.parameters.annualisation.active
        ) {
          AncAppFactory.getControleFacturableAvecFacturationAnnuelle().then(
            (res) => {
                if (
                  report.properties.statut_facture &&
                  report.properties.statut_facture ===
                    'FACTURE_ANNUELLE_EN_COURS'
                ) {
                  if (Array.isArray(res.data) && res.data.length > 0) {
                    const actualYear = new Date().getFullYear();
                    const controleEcheances = res.data.filter(
                      (controle) => controle.referenceControle === report.id
                    );
                    if (controleEcheances && controleEcheances.length > 0) {
                      const controleEcheanceActuelle =
                        controleEcheances.find(
                          (controleEcheance) =>
                            controleEcheance.anneeEcheance === actualYear.toString()
                        );
                      if (controleEcheanceActuelle) {
                        report.properties.echeanceEncours = true;
                      } else {
                        report.cannotCheckEcheance = true;
                        toCheck.tmp.nbErreurs++;
                        report.err.echeance =
                          "Ce contrôle est en cours de facturation annuelle, mais la redevance de l'année en cours est déjà facturée";
                      }
                    } else {
                      report.cannotCheckEcheance = true;
                      toCheck.tmp.nbErreurs++;
                      report.err.echeance =
                        'Ce contrôle est en cours de facturation annuelle, mais on lui trouve aucune écheance dans la table des factures annuelles ';
                    }
                  } else {
                    report.cannotCheckEcheance = true;
                    toCheck.tmp.nbErreurs++;
                    report.err.echeance =
                     'Ce contrôle est en cours de facturation annuelle, mais on lui trouve aucune écheance dans la table des factures annuelles ';
                  }
                }
            }
          );
        }           
        if(report.canCheck) toCheck.tmp.nbErreurs--;
      });
    }

    $scope.getControleName = function(ctrl) {
      return AncAppFactory.getControleName(
        ctrl.properties.type,
        ctrl.properties.date_passage
      );
    };

    $scope.openDossier = function(ctrl) {
      $rootScope.$broadcast('anc_open_dossier', [
        { id: ctrl.properties.ref_dossier },
      ]);
    };
    $scope.openControle = function(ctrl) {
      $rootScope.$broadcast('anc_open_controle', [
        {
          dossier_id: ctrl.properties.ref_dossier,
          controle_id: ctrl.id,
        },
      ]);
    };
    $scope.openVidange = function(vidange) {
      $rootScope.$broadcast('anc_open_vidange', [
        {
          dossier_id: vidange.properties.ref_dossier,
          vidange_id: vidange.id,
        },
      ]);
    };

    /**
     * getServiceInfo
     */
    $scope.getServiceInfo = function(dolibarrId) {
      var service = $scope.periodesCfg.tarification.filter(function(x) {
        return x.dolibarrId == dolibarrId;
      });

      return service.length ? service[0].nom : '#erreur';
    };
    /**
     * getLibelleTypeAssociation
     */
    $scope.getLibelleTypeAssociation = function(type) {
      if (type == 'simple') type = 'Simple';
      if (type == 'modele') type = 'Modèle';
      if (type == 'avance') type = 'Avancée';

      return type;
    };

    /**
     * selectModeleAFacturer
     * On ne peut facturer qu'un seul type à la fois
     */
    $scope.selectModeleAFacturer = function(elemfactu) {
      elemfactu.picked = !elemfactu.picked;
      $scope.currentModeleSelectionne = false;
      resetAFacturer();

      $scope.elementsFacturationEligible.forEach(function(x) {
        delete x.tmp.res;
        if (x.facturationid != elemfactu.facturationid) x.picked = false;
      });

      if (elemfactu.picked) {
        $scope.currentModeleSelectionne = elemfactu;
        $scope.searchForFacturable(elemfactu);
      }
    };

    /**
     * SortQueryResult
     * Tri l'affichage des controles selon le nom ou la ref dossier
     */
    const SortQueryResult = (queryResult, type)=>{
      queryResult.features.sort((a,b) => {
        switch(type){
          case 'Nom':
            if (a.properties[type] > b.properties[type]){
              return 1;
            }
            else if (a.properties[type] < b.properties[type]){
              return -1;
            }
            else{
              return 0;
            }
          case 'reference_dossier_originale':
            if((typeof a.properties) == 'string'){
              if (a.properties[type] > b.properties[type]){
                return 1;
              }
              else if (a.properties[type] < b.properties[type]){
                return -1;
              }
              else{
                return 0;
              }
            }
            else{
              return a.properties[type]-b.properties[type];
            }
          default :
            //ne trie pas
            return 0;
        };
      });
    }

    /**
     * toggle tous les items facturables pour cet element de facturation
     */
    $scope.toggleAllItemsFacturation = function(elemfactu) {
      // reset tous les autres types pour empecher la facturation de plusieurs
      // types en meme temps
      for (let i in $scope.aFacturer) {
        $scope.aFacturer[i] = {};
      }

      // toggle des items
      if (elemfactu.tmp.res.totalFeatures) {
        // delete all
        if (!elemfactu.toggle_all) {
          $scope.aFacturer[elemfactu.facturationid] = {};
          return;
        }
        // add all
        if (!angular.isDefined($scope.aFacturer[elemfactu.facturationid]))
          $scope.aFacturer[elemfactu.facturationid] = {};
        elemfactu.tmp.res.features.map(function(ctrl) {
          if (ctrl.canCheck === true && !ctrl.cannotCheckEcheance) {
            if (
              !angular.isDefined(
                $scope.aFacturer[elemfactu.facturationid][ctrl.id]
              )
            ) {
              $scope.aFacturer[elemfactu.facturationid][ctrl.id] = {
                active: true,
              };
            }
            $scope.toggleFacture(elemfactu, ctrl, 0, elemfactu);
          }
        });
      }
    };

    /**
     * toggle les premiers du nombre sélectionné d'items facturables pour cet
     * element de facturation
     */
    $scope.toggleNumberItemsFacturation = function(elemfactu,numberSelected) {
      // reset tous les autres types pour empecher la facturation de plusieurs
      // types en meme temps
      for (let i in $scope.aFacturer) {
        $scope.aFacturer[i] = {};
      }

      // toggle des items
      if (elemfactu.tmp.res.totalFeatures) {
        // add number selected items
        if (!angular.isDefined($scope.aFacturer[elemfactu.facturationid])){
          $scope.aFacturer[elemfactu.facturationid] = {};
        }
        const selectedControls = elemfactu.tmp.res.features
          .filter(ctrl => ctrl.canCheck === true && !ctrl.cannotCheckEcheance)
          .slice(0,numberSelected);
        for (let ctrl of selectedControls){
          if (!angular.isDefined(
                $scope.aFacturer[elemfactu.facturationid][ctrl.id])){
            $scope.aFacturer[elemfactu.facturationid][ctrl.id] = {active: true};
          }
          $scope.toggleFacture(elemfactu, ctrl, 0, elemfactu);
        }
      }
    };

    /**
     * toggle single item facturation
     *
     * @param {*}
     *            elemfactu
     * @param {*}
     *            controle
     * @param {*}
     *            timeout timeout necessaire (singletoggle) ou pas (depuis
     *            toggleAllItemsFacturation)
     */
    $scope.toggleFacture = function(elemfactu, controle, timeout) {
      var inner = function() {
        if (
          !angular.isDefined(
            $scope.aFacturer[elemfactu.facturationid][controle.id]
          )
        ) {
          $scope.aFacturer[elemfactu.facturationid][controle.id] = {};
        }

        if ($scope.aFacturer[elemfactu.facturationid][controle.id].active) {
          // bloc adresse (@TODO factoriser qqpart)
          var adresseCtrl = '';
          if (controle.properties.adresse_num_rue != null)
            adresseCtrl += controle.properties.adresse_num_rue + ' ';
          if (controle.properties.adresse_num_rue_extra != null)
            adresseCtrl += controle.properties.adresse_num_rue_extra + ' ';
          if (controle.properties.adresse_rue != null)
            adresseCtrl += controle.properties.adresse_rue + ' ';
          adresseCtrl += '\n';
          if (controle.properties.adresse_cp != null)
            adresseCtrl += controle.properties.adresse_cp + ' ';
          if (controle.properties.adresse_ville != null)
            adresseCtrl += controle.properties.adresse_ville + ' ';

          var _infos = {
            controle: controle.id,
            controle_name: AncAppFactory.getControleName(
              controle.properties.type,
              controle.properties.date_passage
            ),
            dossier: controle.properties.ref_dossier,
            dossier_name: controle.properties.reference_dossier_originale,
            debiteur: controle.debiteurFinal,
            occupant:
              controle.occupantFinal !== false
                ? controle.occupantFinal
                : { properties: {} },
            adresse_controle: adresseCtrl,
            type_controle: AncAppFactory.getControleName(
              controle.properties.type,
              false
            ),
          };

          let promises = [];

          if ($scope.facturationSpeciale == 'omega') {            
            if (controle.properties.id_point_conso_omega) {
              _infos.id_point_conso_omega = controle.properties.id_point_conso_omega;
            }  
          }
          // REGARDER DANS BAC (facturationCtrl) COMMENT C'EST FAIT SI MODELE
          // AVANCE != VIDANGE

          // dans le cas des vidanges on rajoute les infos de facturation
          if (angular.isDefined(elemfactu.vidanges)) {
            var factuData = {};
            for (var i in controle.properties) {
              // console.log(i);
              if (i.indexOf('facturation_data') == 0) {
                factuData[i] = controle.properties[i];
              }
            }
            _infos.response_data = factuData;
            _infos.controle_name = 'Vidange';
            _infos.type_controle = 'Vidange';
            _infos.date_controle = controle.properties.date_controle;
          } else {
            // var dateRef = controle.originalProperties.type == 'FO0' ?
            // 'date_demande' : 'date_passage';
            _infos.date_controle = controle.properties['date_passage'];
          }
          _infos.date_controle = moment(_infos.date_controle).format('X');

            $scope.aFacturer[elemfactu.facturationid][controle.id].infos = _infos;
          
        } else {
          delete $scope.aFacturer[elemfactu.facturationid][controle.id];
        }
      };

      if (timeout) {
        var timer = $timeout(function() {
          inner();
          $timeout.cancel(timer);
        });
      } else {
        inner();
      }
    };

    /* information du nb d'elements selectionnes */
    $scope.$watch(
      'aFacturer',
      function(af) {
        if ($scope.aFacturerLength) $scope.aFacturerLength.total = 0;

        for (var i in af) {
          $scope.aFacturerLength[i] = 0;

          for (var j in af[i]) {
            if (af[i][j]) $scope.aFacturerLength[i] += 1;
          }
          $scope.aFacturerLength.total += $scope.aFacturerLength[i];
        }
      },
      1
    );

    $scope.nbFacturesAGenerer = 0;

    function factuDone(res) {
      gaDomUtils.hideGlobalLoader();
      // @INTERFACE JVS
      // @TODO PLUS COMPATIBLE AVEC LE RESTE CI-DESSOUS
      if (dolibarrFactory.cfg.params.facturationTierce.active) {
        require('toastr').success(
          "Retrouver le fichier d'export dans l'onglet <b>Exports Multi-Facturation</b>",
          'Facturation effectuée',
          {
            closeButton: true,
            timeOut: '0',
            extendedTimeOut: '0',
          }
        );
        return;
      }

      if (res.data.critical_error) {
        require('toastr').error(
          'raison : <small>' +
            JSON.stringify(res.data.critical_error) +
            '</small>',
          'Erreur de génération',
          {
            closeButton: true,
            timeOut: '0',
            extendedTimeOut: '0',
          }
        );
        return;
      }

      // generation avec erreurs
      if (res.data.errors.length) {
        var _msg = [];
        for (var i in res.data.errors) {
          _msg.push(
            res.data.errors[i].dossier +
              ' - ' +
              res.data.errors[i].controle +
              ' <br/><small>-> ' +
              res.data.errors[i].type_erreur +
              '</small>'
          );
        }

        var _title =
          res.data.errors.length == 1
            ? 'Facture en erreur :'
            : 'Factures en erreur :';
        require('toastr').error(_msg.join('<br/><br/>') + '.', _title, {
          closeButton: true,
          timeOut: '0',
          extendedTimeOut: '0',
        });
      }

      // générations ok
      if (res.data.controlesFactures != 0) {
        var msg =
          'Factures générées : <b>' + res.data.controlesFactures + '</b>';

        if (res.data.errors.length) {
          msg +=
            '<br/>Factures non générées  : <b>' +
            res.data.errors.length +
            '</b>';
          require('toastr').warning(msg, 'Facturation effectuée', {
            closeButton: true,
            timeOut: '0',
            extendedTimeOut: '0',
          });
        } else {
          require('toastr').success(msg, 'Facturation effectuée', {
            closeButton: true,
            timeOut: '0',
            extendedTimeOut: '0',
          });
        }
      }

      // on relance la recherche sur le modele en cours
      $timeout(function() {
        $scope.searchForFacturable($scope.currentModeleSelectionne);
      }, 600);
    }

    function generatefacturesdolibarr(toGenerate, deep) {
      if (deep == undefined) deep = 0;
      AncAppFactory.generatefacturesdolibarr(toGenerate).then(
        function(res) {
          factuDone(res);
        },
        function() {
          gaDomUtils.hideGlobalLoader();
          require('toastr').error(
            "Une erreur s'est produite lors de la génération des factures"
          );
        }
      );
    }

    /**
     * chooseRealFactOrganismeButton : Choisir le bon organisme de facturation
     */
    $scope.chooseOrgaFacturation =  (param) => {
      param.active =  false;
      param.id = parseInt(param.id)
      const realOrgaFact = {orgaFactu: param}
      OmegaFactory.sendRealOrganisationFact(realOrgaFact).then((res)=>{
        AncAppFactory.appCfg.main.properties.orgaFacturation = res.data
          AncAppFactory.updateAppCfg();
      })
      $scope.selectedOrga = param;
      ngDialog.close();
    }

    /**
     * chooseRealFactOrganismeButton : Ouvrir l'interface de choix de l'organisme de facturation
     */
    $scope.chooseRealFactOrganismeButton =  ()  =>{
      OmegaFactory.getListOfFacturationOrganisations().then((res) =>{
        $scope.listOrgaFacturation = res.data;
        ngDialog.open({
          template: 'js/XG/widgets/ancapp/main/views/chooseOrgaFacturation.html',
          className: 'ngdialog-theme-plain noclose',
          closeByDocument: false,
          scope: $scope
        });
      })
    }

    /**
     * generateFacturesv2 Dolibarr
     */
    $scope.generateFacturesv2 = function(conf) {
      ans = true;
      if (conf == undefined) {
        var ans = confirm(
          'Êtes-vous certain de vouloir générer les factures correpondant aux contrôles sélectionnés?'
        );
      }
      if (ans) {
        gaDomUtils.showGlobalLoader();

        var params = angular.copy($scope.generation_filter);

        params.date_generation_plain = moment(params.date_generation).format(
          'YYYY-MM-DD'
        );
        params.date_echeance_plain = moment(params.date_echeance).format(
          'YYYY-MM-DD'
        );
        params.date_generation_ts = moment(params.date_generation).format('X');
        params.date_echeance_ts = moment(params.date_echeance).format('X');
        params.date_debut_ts = moment(params.debut).format('X');
        params.date_fin_ts = moment(params.fin).format('X');
      
        var toGenerate = {
          dolibarrCfg: dolibarrFactory.cfg,
          params: params,
          aFacturer: [],
        };
  
        // pour la facturation Annuelle On fait les insertions ou l update dans la table 
        // Kis_anc_dossier_facture_anuelle

        // pour chaque element de facturation selectionne
        for (var i in $scope.elementsFacturationEligible) {
          var efe = $scope.elementsFacturationEligible[i];

          if (angular.isDefined($scope.aFacturer[efe.facturationid])) {
            console.log('FACTURATION DE ' + efe.facturationid);

            // on recupere les infos sur la periode
            for (var i in $scope.periodesCfg.periodes) {
              if ($scope.periodesCfg.periodes[i].key == efe.periode) {
                toGenerate.params.periodeCfg = angular.copy(
                  $scope.periodesCfg.periodes[i]
                );
                toGenerate.params.periodeCfg.deliberation = moment(
                  toGenerate.params.periodeCfg.deliberation
                ).format('X');
                toGenerate.params.periodeCfg.debut = moment(
                  toGenerate.params.periodeCfg.debut
                ).format('X');
                toGenerate.params.periodeCfg.fin = moment(
                  toGenerate.params.periodeCfg.fin
                ).format('X');
              }
            }

            var controles = [];
            for (var ctrl in $scope.aFacturer[efe.facturationid]) {
              if ($scope.aFacturer[efe.facturationid][ctrl].active)
                controles.push($scope.aFacturer[efe.facturationid][ctrl].infos);
            }

            if (controles.length) {
              // set les infos du service directement ici pour le moment,
              // TODO : a gerer coté serveur lorsque les configurations
              // avancées seront gérées
              var associations = angular.copy(efe.associations);
              if (associations.type == 'simple') {
                var service = $scope.periodesCfg.tarification.filter(function(
                  x
                ) {
                  return x.dolibarrId == associations.services;
                });
                associations.services = service[0];
              }
              // retourne tous les services utilises sur cette periode, avec
              // dolibarrId en key
              if (associations.type == 'avance') {
                var servicesUtilises = {};
                for (var i in $scope.periodesCfg.tarification) {
                  if (
                    $scope.periodesCfg.tarification[i].periode == efe.periode
                  ) {
                    servicesUtilises[
                      $scope.periodesCfg.tarification[i].dolibarrId
                    ] = $scope.periodesCfg.tarification[i];
                  }
                }

                associations.services = servicesUtilises;
              }

              toGenerate.aFacturer.push({
                element_facturation: {
                  nom: efe.nom,
                  debiteur: efe.debiteur,
                  associations: associations,
                  parameters : efe.parameters ? efe.parameters : {},
                  type_facturation: angular.isDefined(efe.vidanges)
                    ? 'vidanges'
                    : 'controles',
                },
                
                controles: controles,
                debiteurs: {
                  type: 'FeatureCollection',
                  features: controles.map(function(x) {
                    return x.debiteur;
                  }),
                },
              });

              // @INTERFACE JVS
              if ($scope.facturationSpeciale == 'multifac') {
                var toGenerateJVS = {
                  cfg: {},
                  data: [],
                };

                try {
                  // debiteur
                  var _d = controles.map(function(x) {
                    return x.debiteur;
                  })[0];

                  var _dp = _d.properties;

                  // @TODO TESTER AVEC UN DEBITEUR DEMANDEUR !

                  var _debiteur = {
                    numero: _d.id.replace('kis_anc_', '').slice(0, 20),
                    civilite: _dp.civilite ? _dp.civilite.slice(0.1) : '',
                    nom: _dp.nom ? _dp.nom.slice(0, 50) : 'nom_manquant',
                    prenom: _dp.prenom
                      ? _dp.prenom.slice(0, 50)
                      : 'prenom_manquant',
                    dateNaissance: $filter('date')(
                      moment(_dp.date_naissance).toDate(),
                      'yyyyMMdd'
                    ),
                    email: _dp.email ? _dp.email.slice(0, 50) : '',
                    num_tel: _dp.num_tel ? _dp.num_tel.slice(0, 15) : '',
                    num_port: _dp.num_port ? _dp.num_port.slice(0, 15) : '',
                    fax: _dp.fax ? _dp.fax.slice(0, 15) : '',
                    adresse: {
                      num_rue: _dp.adresse_num_rue
                        ? _dp.adresse_num_rue.toString().slice(0, 5)
                        : '',
                      num_rue_extra: _dp.adresse_num_rue_extra
                        ? _dp.adresse_num_rue_extra.slice(0, 10)
                        : '',
                      rue: _dp.adresse_rue ? _dp.adresse_rue.slice(0, 50) : '',
                      cp: _dp.adresse_cp
                        ? _dp.adresse_cp.toString().slice(0, 5)
                        : '',
                      commune: _dp.adresse_ville
                        ? _dp.adresse_ville.slice(0, 50)
                        : '',
                      pays: _dp.fax ? _dp.fax.slice(0, 15) : '',
                    },
                  };

                  // facturation simple + avancée

                  toGenerateJVS.data.push({
                    abonne: {
                      numero: _debiteur.numero, // Alphanumérique (20) Référence
                      // unique identifiant l’abonné
                      natJur: '01', // Alphanumérique (2) Se référer à la liste
                      // PES 01->Particuliers (02->Artisan /
                      // Commerçant / Agriculteur,03->Société,...)
                      catTiers: '01', // Alphanumérique (2) Se référer à la
                      // liste PES 01->personnes physiques
                      // (20->Etat et établissements publics
                      // nationaux,...)
                      // -- Catégorie du tiers: 60 : Personnes morales de
                      // droit privé autres qu'organismes sociaux.
                      idTiers: '', // Alphanumérique (18) Identifiant national
                      // du Tiers
                      natIdTiers: '', // Alphanumérique (2) Se référer à la
                      // liste PES
                      civilite: _debiteur.civilite, // Alphanumérique (10)
                      nom: _debiteur.nom, // Alphanumérique (50)
                      prenom: _debiteur.prenom, // Alphanumérique (50)
                      dateNaissance: _debiteur.dateNaissance, // Format
                      // attendu:
                      // AAAAMMJJ
                      email: _debiteur.email, // Alphanumérique (50)
                      telephone: _debiteur.num_tel, // Alphanumérique (15)
                      portable: _debiteur.num_port, // Alphanumérique (15)
                      // "telephone2": "01.02.03.04.05",
                      // "portable2": "",
                      fax: _debiteur.fax, // Alphanumérique (15)
                      // @TODO
                      groupe: 'UN GROUPE', // Alphanumérique (50) Groupe devant
                      // exister dans la MF.
                      commentaireInterne: 'test\r\ntest\r\n',
                      commentaireFacture: '',
                      adresse: {
                        cplIdent: '',
                        cplGeo: '',
                        noVoie: _debiteur.adresse.num_rue, // Alphanumérique
                        // (5)
                        lettre: _debiteur.adresse.num_rue_extra, // Alphanumérique
                        // (10)
                        cplNoVoie: '',
                        voie: _debiteur.adresse.rue, // Alphanumérique (50)
                        cplDistrib: '',
                        codePostal: _debiteur.adresse.cp, // Alphanumérique
                        // (5)
                        commune: _debiteur.adresse.commune, // Alphanumérique
                        // (50)
                        // @TODO GERER LE PAYS
                        pays: '', // Alphanumérique (70) Vide ou FRANCE pour
                        // une adresse en France Sinon l’adresse
                        // sera considérée à l’étranger
                      },
                      aFacturer: [
                        {
                          nomCategorie: 'GENERAL',
                          dateEffet: '',
                          variable: [
                            {
                              nom: efe.nom,
                              valeur: '1',
                            },
                          ],
                        },
                      ],
                    },
                  });
                } catch (error) {
                  // JVS ERROR #33
                  require('toastr').error(
                    "Une erreur s'est produite lors de la génération des factures (#33)"
                  );
                  console.log('%c  ' + error, 'background: #f00; color: #fff');
                  gaDomUtils.hideGlobalLoader();
                }
              }

              if ($scope.facturationSpeciale == 'omega') {
                var aFacturer = [];
                for (var key in controles) {
                  if (controles.hasOwnProperty(key)) {
                    var element = {};
                    element.idOmega = controles[key].id_point_conso_omega;
                    element.idControle = controles[key].controle;
                    element.controleType = controles[key].type_controle;
                    element.debiteur = controles[key].debiteur;
                    aFacturer.push(element);
                  }
                }

                var toGenerateOmega = {
                  associations: associations,
                  aFacturer: aFacturer,
                  portal: $rootScope.xgos.portal.uid,
                  datastore: AncAppFactory.appCfg.main.datastore
                };
                console.log(toGenerate)

                try {
                } catch (error) {
                  // JVS ERROR #34
                  require('toastr').error(
                    "Une erreur s'est produite lors de la génération des factures (#34)"
                  );
                  console.log('%c  ' + error, 'background: #f00; color: #fff');
                  gaDomUtils.hideGlobalLoader();
                }
              }
            }
          }
        }

        // ---------------------------------
        // PRET A FACTURER
        // ---------------------------------
        if ($scope.facturationSpeciale == 'omega') {
          gaDomUtils.hideGlobalLoader();
          if (!Object.keys(toGenerateOmega).includes('idRealOrgaFactu')) {
            toGenerateOmega['idRealOrgaFactu'] = '';
          }
          // on attribut la valeur -1 ( l id de l organisme ne peut être égale à -1 et il y a un test en backend sur une varibale integer qui recupere celle ci basé, donc ne doit pas être null)
          let idRealOrgaFactu = -1;
          // id de l'organisme de facturation réel (choisi par l'utilisateur)
          if (AncAppFactory.appCfg.main.properties.orgaFacturation && AncAppFactory.appCfg.main.properties.orgaFacturation.id) {
              idRealOrgaFactu = AncAppFactory.appCfg.main.properties.orgaFacturation.id
          }
          toGenerateOmega.idRealOrgaFactu = idRealOrgaFactu
      
          var promise = OmegaFactory.generateBillOmega(toGenerateOmega);
          promise.then(
            function(res) {
              require('toastr').success(
                "Les factures sont en cours d'acceptation dans omega",
                'Facturation effectuée',
                {
                  closeButton: true,
                  timeOut: '0',
                  extendedTimeOut: '0',
                }
              );
              gaDomUtils.hideGlobalLoader();
            },
            function() {
              require('toastr').error(
                'Erreur lors de la generation de facture omega',
                '',
                {
                  closeButton: true,
                  timeOut: '0',
                  extendedTimeOut: '0',
                }
              );
              gaDomUtils.hideGlobalLoader();
            }
          );

          for (var i in $scope.elementsFacturationEligible) {
            if ($scope.elementsFacturationEligible[i].tmp) {
              if ($scope.elementsFacturationEligible[i].tmp.res) {
                if ($scope.elementsFacturationEligible[i].tmp.res.totalFeatures) {
                  $scope.elementsFacturationEligible[i].tmp.res.totalFeatures = 0;
                }
              }
            }
          }
          return promise;
        }

        // @INTERFACE JVS MULTIFAC
        if ($scope.facturationSpeciale == 'multifac') {
          gaDomUtils.hideGlobalLoader();
          toGenerate = toGenerateJVS;
          return;
        }

        generatefacturesdolibarr(toGenerate);
      }
    };

    $scope.getAndCheckStatusFacture = function(idFacture) {
      var factureCheckStatusOmega = {
        idFacture: idFacture,
        datastore: AncAppFactory.appCfg.main.datastore,
      };
      if ($scope.facturationSpeciale == 'omega') {
        gaDomUtils.hideGlobalLoader();
        var promise = OmegaFactory.getAndCheckStatusFactureOmega(
          factureCheckStatusOmega
        );
        promise.then(
          function(res) {},
          function() {}
        );
        return promise;
      }
    };

    /***************************************************************************
     * SYNTHESE
     **************************************************************************/

    $scope.periodesFacturation = false;
    $scope.periodesFacturationFti = angular.copy(
      FeatureTypeFactory.getFeatureByNameAndDatastore(
        AncAppFactory.appCfg.main.datastore,
        'kis_anc_factures_periodes'
      )
    );
    $scope.$watch('facturationTabs.activeTab', function(t) {
      if (t == 1) {
        QueryFactory.data($scope.periodesFacturationFti.uid).then(function(
          res
        ) {
          // enlever la meme periode de facturation
          var tableau_label = [];
          var tableau_res = [];
          for (var i = 0; i < res.data.features.length; i++) {
            var date =
              res.data.features[i].properties.debut +
              res.data.features[i].properties.fin;
            if (tableau_label.indexOf(date) == -1) {
              tableau_label.push(date);
              tableau_res.push(res.data.features[i]);
            }
          }
          $scope.periodesFacturation = tableau_res;
        });
      }
    });

    $scope.controleCfg = AncAppFactory.appCfg.main.controleCfg;

    $scope.selectedFactures = { liste: [] };
    $scope.facturesFti = angular.copy(
      FeatureTypeFactory.getFeatureByNameAndDatastore(
        AncAppFactory.appCfg.main.datastore,
        'kis_anc_controle_factures'
      )
    );
    $scope.factureAttributes = [];
    $scope.facturesFti.attributes.forEach(function(att) {
      if (
        ~[
          'numerofacture',
          'est_facture',
          'est_regle',
          'est_annule',
          'nom_debiteur',
          'prenom_debiteur',
          'date_generation',
          'date_echeance',
        ].indexOf(att.name)
      ) {
        $scope.factureAttributes.push(att);
      }
    });

    $scope.factureButtonActions = [
      {
        label: 'btn',
        btnclass: 'default',
        cfg: {
          icon: {
            name: 'download',
            spinning: false,
          },
          iconOrLabel: 'label',
          size: 'btn-xs',
          style: 'btn-default',
          label: 'html',
        },
        config: { click: ['showFacture'] },
      },
      {
        label: 'btn',
        btnclass: 'default',
        cfg: {
          icon: {
            name: 'download',
            spinning: false,
          },
          iconOrLabel: 'label',
          size: 'btn-xs',
          style: 'btn-default',
          label: 'pdf',
        },
        config: { click: ['showFacturePDF'] },
      },
    ];

    $scope.synthese_filter = {};

    /**
     * facture clicked from synthese factures datatable
     *
     * @param args
     */
    $scope.actionFromListeFactures = function(args) {
      var facture = $scope.selectedFactures.liste[0];
      var action = args[0];
      var reference_controle = facture.properties.reference_controle;

      if (action == 'showFacture') {
        gaDomUtils.showGlobalLoader();
        FeatureAttachmentFactory.getdownloadurl(
          facture.properties.numerofacture + '.html',
          'kis_anc_dossier_controle',
          reference_controle
        ).then(function(res) {
          gaDomUtils.hideGlobalLoader();
          window.open(res.data);
        });
      }

      if (action == 'showFacturePDF') {
        gaDomUtils.showGlobalLoader();
        FeatureAttachmentFactory.getdownloadurl(
          facture.properties.numerofacture + '.pdf',
          'kis_anc_dossier_controle',
          reference_controle
        ).then(function(res) {
          gaDomUtils.hideGlobalLoader();
          window.open(res.data);
        });
      }
    };

    /**
     *
     */
    var refreshFacturesGraphiques = function(where) {
      AncAppFactory.getmontantfactures(where).then(function(res) {
        $scope.factureFilter = { where: where };
        $scope.montantsData = res.data;
        $scope.totauxData = {
          facture: 0,
          regle: 0,
          annule: 0,
        };

        var labels = [];
        var series = [[], [], []];
        /*
         * var series = [{ className: 'facture', name: 'facture', data: [], },{
         * className: 'regle', name: 'regle', data: [], },{ className: 'annule',
         * name: 'annule', data: [], }];
         */
        for (var i in $scope.controleCfg) {
          var type = $scope.controleCfg[i].type;
          labels.push(type);
          if (angular.isDefined(res.data[type])) {
            series[0].push(res.data[type].facture);
            $scope.totauxData.facture += res.data[type].facture;
            series[1].push(res.data[type].regle);
            $scope.totauxData.regle += res.data[type].regle;
            series[2].push(res.data[type].annule);
            $scope.totauxData.annule += res.data[type].annule;
          } else {
            $scope.montantsData[type] = {
              facture: 0,
              regle: 0,
              annule: 0,
            };
          }
        }

        var facturationChart = Chartist.Bar(
          '.ct-chart',
          {
            labels: labels,
            series: series,
          },
          {
            seriesBarDistance: 15,
            height: 300,
          }
        );

        /*
         * var seq = 0; facturationChart.on('created', function() { seq = 0; });
         *
         * facturationChart.on('draw', function(data) {
         *
         * if(data.type === 'bar') {
         *
         * console.log(data); console.log(data.group());
         *
         * if(data.value!=0){
         *
         *
         * console.log('yo');
         *
         * var vfrom = $scope.previousBarValues[data.index] ?
         * $scope.previousBarValues[data.index] : 265;
         * $scope.previousBarValues[data.index] = data.y2;
         *
         * data.element.animate({ y2: { begin: seq++ * 180, dur: 500, from:
         * vfrom, to:data.y2 }, }); } } });
         */
      });
    };

    /**
     * refreshListePourSyntheseFacture
     */
    $scope.previousBarValues = {};
    $scope.refreshListePourSyntheseFacture = function() {
      var where = '';
      var sf = angular.copy($scope.synthese_filter);

      where +=
        "date_generation >= '" +
        $filter('date')(
          moment(sf.periode.properties.debut)
            .hours(0)
            .minutes(0)
            .toDate(),
          'yyyy-MM-ddTHH:mm:ss.sssZ'
        ) +
        "' AND  " +
        " date_generation <= '" +
        $filter('date')(
          moment(sf.periode.properties.fin)
            .hours(23)
            .minutes(59)
            .toDate(),
          'yyyy-MM-ddTHH:mm:ss.sssZ'
        ) +
        "'";

      if (where != '') {
        refreshFacturesGraphiques(where);
      }
    };

    /**
     *
     * @param action
     */
    $scope.changeStatutFactures = function(action) {
      var ans = confirm(
        'Êtes-vous certain de vouloir modifier le statut de ces factures ?'
      );
      if (ans) {
        var toChange = $scope.selectedFactures.liste.map(function(c) {
          return c.id;
        });
        gaDomUtils.showGlobalLoader();
        AncAppFactory.changestatutfactures(toChange, action).then(function() {
          gaDomUtils.hideGlobalLoader();
          $rootScope.$broadcast('refreshDatatable', {
            uid: $scope.facturesFti.uid,
          });
          $timeout(function() {
            $scope.refreshListePourSyntheseFacture();
          });
        });
      }
    };

    var booleanToCheck = function(v) {
      return $filter('booleanToCheck')(v);
    };
    $scope.renderFacturesCol = {
      est_facture: booleanToCheck,
      est_regle: booleanToCheck,
      est_annule: booleanToCheck,
    };

    $scope.imprimerFactures = function() {
      var pdata = {
        type: 'FeatureCollection',
        features: $scope.selectedFactures.liste,
      };
      AncAppFactory.imprimerfactures(pdata).then(function(res) {
        // service level logic if any
        console.log(res.data);
        var chemin = res.data.split(';');
        window.open(
          '/services/' +
            chemin[1] +
            '/documents/downloadtemplate?' +
            '&name=' +
            chemin[0]
        );
      });
    };

    $scope.getFacturesPDF = function() {
      var pdata = {
        type: 'FeatureCollection',
        features: $scope.selectedFactures.liste,
      };
      AncAppFactory.getfacturespdf(pdata).then(function(res) {
        // service level logic if any
        console.log(res.data);
        var chemin = res.data.split(';');
        if (res.data && res.data != '' && chemin.length && chemin[0] != '') {
          window.open(
            '/services/' +
              chemin[1] +
              '/documents/downloadtemplate?' +
              '&name=' +
              chemin[0]
          );
        } else {
          require('toastr').error('PDF pas disponible.');
        }
      });
    };

    /**
     * getControlesConcernesParTemplate
     *
     * @param {*}
     *            x
     */
    $scope.getControlesConcernesParTemplate = function(x) {
      if (!x.controles) return 'aucun';
      return Object.keys(x.controles)
        .filter(function(k, i) {
          return x.controles[k].selected === true;
        })
        .join(', ');
    };

    $scope.getlisteexportsjvs = function() {
      $scope.exportsJvs = [];
      gaDomUtils.showGlobalLoader();

      AncAppFactory.getlisteexportsjvs().then(
        function(res) {
          $scope.exportsJvs = res.data;
          gaDomUtils.hideGlobalLoader();
        },
        function() {
          require('toastr').error(
            'Erreur lors de la récupérations des exports Multi-Facturation.'
          );
          gaDomUtils.hideGlobalLoader();
        }
      );
    };

    $scope.downloadjvsfile = function(name) {
      window.open(
        '/services/' +
          $rootScope.xgos.portal.uid +
          '/ancapp/getjvsfile?f=json&name=' +
          name
      );
    };
    function resolveControleFti(request) {
      request.elasticQuery.jointure.forEach(() => {
        $scope.elementsFacturationEligible.push(request);
      });
    }

    function resolveFiliere(request) {
      const fillieres = (request.extraCriterias || []).reduce(
        (obj, extraCriteria) => {
          if (extraCriteria.fid.startsWith('kis_anc_ef_')) {
            obj[extraCriteria.fid] = (obj[extraCriteria.fid] || []).concat([
              extraCriteria,
            ]);
          }
          return obj;
        },
        {}
      );
      if (!Object.keys(fillieres)) {
        return request;
      }
      request.elasticQuery.relations[0].filters.map(filter => {
        if (
          filter.choice === 'relation' &&
          filter.relation_DOSSIER_CONTROLE_choosen &&
          filter.relation_DOSSIER_CONTROLE_choosen.name === 'kis_anc_dossier'
        ) {
          filter.filters.push({
            alias: 'Filière des dossiers',
            attr: {},
            choice: 'relation',
            relation_DOSSIER_CONTROLE_choosen: {
              name: 'kis_anc_dossier_filiere',
            },
            selectGlobaladvancedFti: 'kis_anc_dossier_filiere',
            choices: [$filter('translate')('elastic.search.anc.contient')],
            choicesdone: $filter('translate')('elastic.search.anc.contient'),
            selectedfti: FeatureTypeFactory.resources.featuretypes.find(
              feature => feature.name === 'kis_anc_dossier_filiere'
            ),
            filters: Object.values(fillieres).map(filiere => {
              return {
                alias: filiere[0].filter.selectedfti.alias,
                attr: {},
                choice: 'relation',
                choices: [$filter('translate')('elastic.search.anc.contient')],
                choicesdone: $filter('translate')(
                  'elastic.search.anc.contient'
                ),
                relation_DOSSIER_CONTROLE_choosen: {
                  name: filiere[0].fid,
                },
                selectGlobaladvancedFti: filiere[0].filter.selectedfti.alias,
                selectedfti: angular.copy(filiere[0].filter.selectedfti),
                filters: filiere.map(filier => filier.filter),
              };
            }),
          });
        }
      });
      request.elasticQuery.relations[0].filters = request.elasticQuery.relations[0].filters.filter(
        filter =>
          !filter.selectedfti ||
          !filter.selectedfti.uid.startsWith('kis_anc_ef_')
      );
      request.extraCriterias = request.extraCriterias.filter(
        extraCriteria => !extraCriteria.fid.startsWith('kis_anc_ef_')
      );
      return request;
    }
  };

  facturationCtrl.$inject = [
    '$scope',
    'AncAppFactory',
    'FeatureTypeFactory',
    '$filter',
    'QueryFactory',
    'gaDomUtils',
    '$timeout',
    'FeatureAttachmentFactory',
    '$rootScope',
    'gaJsUtils',
    'dolibarrFactory',
    'AncAppSearchFactory',
    '$q',
    'OmegaFactory',
    'ngDialog',
  ];
  return facturationCtrl;
});
