'use strict';
define(function () {
  var listeDossiersBac = function (
    BacAppFactory,
    FeatureTypeFactory,
    $filter,
    $rootScope,
    ngDialog,
    gaDomUtils,
    FeatureHistoryFactory,
    $timeout,
    QueryFactory,
    EditFactory,
    $sce,
    DocumentFactory,
    $q,
    CalendarFactory,
    gaJsUtils,
    UsersFactory,
    $location,
    FeatureAttachmentFactory,
    gclayers,
    gcWMS,
    panelsManager,
    BaseMapFactory,
    ConfigFactory,
    kisCalendarFactory,
    ancBacTools,
    uiCalendarConfig,
    dateUtils,
    HtmlUtils,
    ParametersFactory
  ) {
    return {
      templateUrl:
        'js/XG/widgets/bacapp/main/views/directives/liste_dossiers_bac.html',
      restrict: 'EA',
      scope: {
        type: '=',
        appname: '=?',
        datatableHeight: '=?',
        mainMap: '=?',
        mobile: '=?',
        externalDossierFilter: '=?', // extra dossier filter used on the map for instance, to prefilter dossiers
        idsfilter: '=?', // Used for tournee get dossiers
        globalfilter: '=?',
        res: '=?',
        canDeleteControleBac: '=?'
      },
      link: (scope) => {
        let dossierDateNames = [
          'alerte_echeance',
          'date_creation',
          'date_raccordement',
          'date_dernier_controle',
          'date_prochain_controle',
          'date_etat_raccordement',
          'date_derogation',
        ];

        scope.canDeleteControleBac = () => 
          $rootScope.xgos.user.roles.some(
            (role) => 
            role.name === 'rootUser' ||
            role.name === 'sRootUser' ||
            role.name === 'BAC_responsable');

        /**
         * nombre des lignes a afficher dans le tableau de la liste des dossiers
         */
        scope.startCount = BacAppFactory.appCfg.main.properties.gcDataTableCount;
        /**
         * Vérification de l'existance de controle de type CCI
         */
        scope.existCCIControle = false;
        scope.currentControlesIncludeCCI = () => {
          scope.existCCIControle = false;
          if (scope.currentControles) {
            scope.currentControles.forEach((currentControle) => {
              if (currentControle.properties.type == 'CCI') {
                scope.existCCIControle = true;
              }
            });
          }
        };
        scope.$watch('currentControles', (tab) => {
          scope.currentControlesIncludeCCI();
          if (scope.existCCIControle) {
            $rootScope.$broadcast('existCCIControleEvent');
          }
        });

        scope.documentsCheckedForMail = [];
        if (!angular.isDefined(scope.datatableHeight)) {
          scope.datatableHeight = '1000px';
        }
        console.log(scope.res);
        scope.apptype = 'bac';

        if (
          typeof userAndroid !== 'undefined' &&
          typeof cfgandroid !== 'undefined'
        ) {
          scope.cfgandroid = cfgandroid;
          $rootScope.xgos = { user: {} };
          $rootScope.xgos.sector = 'bac';

          const user = userAndroid.getUser();
          if (!user || user === 'ERROR') {
            AppAndroid.setConf(false);
          } else {
            AppAndroid.setConf(true);
            $rootScope.xgos.user = JSON.parse(user);
          }

          BacAppFactory.appCfg = { main: {}, appName: 'bac' };
          BacAppFactory.appCfg.main = JSON.parse(
            cfgandroid.get('main', 'mainConfig', 'bac')
          );
          BacAppFactory.initappCfg(BacAppFactory.appCfg);
        }
        if (typeof ancAppAndroid !== 'undefined') {
          scope.ancAppAndroid = ancAppAndroid;
          gaDomUtils.showGlobalLoader();
        }
        if (typeof ancAppAndroid == 'undefined') {
          scope.priseRDV = BacAppFactory.appCfg.main.properties.priseRdv;
        }
        scope.dossierBbox = BacAppFactory.appCfg.main.mapConfiguration.bbox;
        scope.avisCtrl = BacAppFactory.appCfg.main.dossierCfg.avisControles;
        scope.appCfgProperties = BacAppFactory.appCfg.main.properties;

        const controleFti = FeatureTypeFactory.getFeatureByNameAndDatastore(
          BacAppFactory.appCfg.main.datastore,
          'kis_bac_dossier_controle'
        );

        scope.parcellesFti = FeatureTypeFactory.getFeatureByNameAndDatastore(
          BacAppFactory.appCfg.main.datastore,
          BacAppFactory.appCfg.main.parcellesCfg.emplacement
        );
        scope.controleFti = controleFti;

        //Récupération configuration des contrôles chargement de la datatable
        scope.allCtrlConfig = {};
        BacAppFactory.getAllCtrlFormCfg('bac').then((res) => {
          scope.allCtrlConfig = res.data;
        });

        scope.feedMode = true;
        scope.toggleDisplayFeed = () => {
          scope.feedMode = scope.feedMode === false;
          $rootScope.$broadcast('toggleDisplayFeeder');
        };

        scope.feedModeDossier = true;

        scope.toggleDisplayFeedDossier = () => {
          scope.feedModeDossier = scope.feedModeDossier === false;
          $rootScope.$broadcast('toggleDisplayFeederDossier');
        };

        scope.displayFeedDossier = false;

        scope.$on('toggleDisplayFeederDossier', () => {
          if (!scope.isMobile) {
            scope.displayFeedDossier = !scope.displayFeedDossier;
            if (!scope.displayFeedDossier) {
              let feederElement = $('.feederKey');
              feederElement.parent().remove();
              feederElement.remove();
            } else {
              $('input:not(#bacListeDossiers input)').each(() => {
                HtmlUtils.feedInputSignet(this);
              });

              $('textarea')
                .not('#bacListeDossiers textarea')
                .each(() => {
                  HtmlUtils.feedTextareaSignet(this);
                });

              $(
                'select.form-control:not(#bacListeDossiers > *, .mainListeDossierActions > *, .loadingReports > *, .ancBacMainList > *)'
              ).each(() => {
                HtmlUtils.feedSelectFormControlSignet(this);
              });

              $(
                'select:not(#bacListeDossiers > *, .mainListeDossierActions > *, .loadingReports > *, .ancBacMainList > *)'
              ).each(() => {
                HtmlUtils.feedSelectOtherSignet(this);
              });

              $('[form-field]:not(#bacListeDossiers > *)').each(() => {
                HtmlUtils.feedFormControlSignet(this);
              });

              $('span.feederKey').on('click', () => {
                HtmlUtils.clickOnFeederKey(this);
              });
            }
          }
        });

        /******************************
                 LISTE DES DOSSIERS
        ******************************/

        scope.dossierFti = angular.copy(
          FeatureTypeFactory.getFeatureByNameAndDatastore(
            BacAppFactory.appCfg.main.datastore,
            'kis_bac_dossier'
          )
        );

        let listeDossiersCfg = BacAppFactory.getListeDossiersCfg(
          scope.dossierFti
        );
        scope.dossierAttributes = listeDossiersCfg['attributes'];
        scope.buttonEditIcon = listeDossiersCfg['editButton'];
        scope.renduTitleColonneDossier =
          listeDossiersCfg['renduTitleColonneDossier'];
        scope.renduColonnesEtatDossier =
          listeDossiersCfg['renduColonnesEtatDossier'];
        scope.filterRender = listeDossiersCfg['filterRender'];
        scope.extraFilterRender = listeDossiersCfg['extraFilterRender'];
        scope.choixStatutRDV = BacAppFactory.getChoixStatutRDV();

        scope.dossierAttributesRaccordes =
          listeDossiersCfg['attributes_raccordes'];

        scope.controleAttributes = [];

        controleFti.attributes.forEach((att) => {
          if (
            ~[
              'type',
              'agent',
              'etat',
              'date_saisie_controle',
              'date_passage',
              'date_passage_rdv',
              'date_avis',
              'statut_facture',
              'statut_rdv',
              'subvention',
            ].indexOf(att.name)
          ) {
            scope.controleAttributes.push(att);
          }
        });

        scope.typesControle = BacAppFactory.appCfg.main.controleCfg;

        // liste des tabs principaux
        scope.reportTabs = [
          {
            title: 'Tous les dossiers',
            key: 'tous',
          },
        ];
        scope.typesControle.forEach((tc) => {
          scope.reportTabs.push({
            title: tc.label_court,
            key: tc.type,
          });
        });

        // this variable is used in editReportComplete and must be global!!
        let listeDesVillesActives;
        if (BacAppFactory.appCfg.main.infosSassListeVillesCfg) {
          listeDesVillesActives = BacAppFactory.appCfg.main.infosSassListeVillesCfg.filter(
            (x) => {
              return x.gere_sass;
            }
          );
        }

        scope.reportTabs.activeTab = 0;
        scope.reportsLength = { v: -1 };

        /** store the reports id returned by elasticsearch to feed the datatable **/
        if (scope.dossierFti != null && scope.controleFti != null) {
          scope.restrictFtids = [scope.dossierFti.uid, controleFti.uid];
        }
        scope.filterfti = { x: {} };
        scope.advancedFiltersResult = { res: {} };
        let filteredReportsIds = [];
        let setFilteredReportsIds = () => {
          filteredReportsIds = [];
          if (
            scope.reportTabs[scope.reportTabs.activeTab] &&
            scope.reportTabs[scope.reportTabs.activeTab].key ===
              'advanced_filters'
          ) {
            // controle / dossier ?
            // global var
            var deregWatchFilters = scope.$watch(
              'advancedFiltersResult',
              (af) => {
                if (af.res.totalFeatures > 0) {
                  filteredReportsIds = af.res.features.map((f) => {
                    return f.id;
                  });
                }
                scope.refreshReports();
              },
              1
            );
          } else {
            if (deregWatchFilters) {
              deregWatchFilters();
            }
          }
        };

        /**
         * when a tab is selected
         */
        scope.$watch('reportTabs.activeTab', (tab) => {
          setFilteredReportsIds();
          if (angular.isDefined(tab)) scope.refreshReports(1);
        });

        scope.controleTableActions = [
          {
            label: 'btn',
            btnclass: 'default',
            cfg: {
              iconOrLabel: 'icon',
              label: 'Afficher',
              size: 'btn-xs',
            },
          },
        ];

        scope.clickOnControle = (expr, controle) => {
          const controle_id = controle.id;
          const dossier_id = controle.properties.ref_dossier;

          gaDomUtils.showGlobalLoader();
          BacAppFactory.getdossier(dossier_id).then((res) => {
            gaDomUtils.hideGlobalLoader();
            scope.editReport(res.data.features[0], false, controle_id);
          });
        };

        /** advanced filters */

        /**
         * set correct dates format..
         * @param properties
         */
        let setDossierDatesFormat = (properties) => {
          [
            'date_creation',
            'date_dernier_controle',
            'date_prochain_controle',
          ].forEach((x) => {
            properties[x] = $filter('date')(
              properties[x],
              'yyyy-MM-ddTHH:mm:ss.sssZ'
            );
          });
        };

        /**
         * refreshCurrentReport
         * @returns {*}
         */
        scope.refreshCurrentReport = () => {
          if (
            angular.isDefined(scope.currentReport) &&
            angular.isDefined(scope.currentReport.id)
          ) {
            BacAppFactory.getdossier(scope.currentReport.id).then((res) => {
              const report = res.data.features[0],
                props = report.properties;
              setDossierDatesFormat(props);
              scope.currentReportTitle = $sce.trustAsHtml(
                ancBacTools.setDossierFullname(
                  report,
                  'bac',
                  initCopyReportButton,
                  $location
                )
              );
              dateUtils.convertAllDatesToDateString(props, dossierDateNames);
              scope.currentReport.properties = props;
              scope.currentControlesIncludeCCI();
              if (scope.existCCIControle) {
                $rootScope.$broadcast('existCCIControleEvent');
              }
            });
          }
        };

        /**
         * refreshReports
         * @param noselfrefresh
         */
        scope.refreshReports = (noselfrefresh) => {
          if (!noselfrefresh) {
            scope.refreshCurrentReport();
          }
          $rootScope.$broadcast('refreshDatatable', {
            uid: scope.dossierFti == null ? null : scope.dossierFti.uid,
          });
        };

        /**
         * when a tab is selected
         */
        scope.$watch('reportTabs.activeTab', (tab) => {
          setFilteredReportsIds();
          if (angular.isDefined(tab)) scope.refreshReports();
        });

        scope.dossierFilterBtn = { v: 'en_cours' };
        scope.innerWhere = false;
        scope.externalWhere = false;

        let setDataTableWhere = () => {
          scope.listeDossiersWhere =
            (scope.innerWhere || '1=1') +
            ' AND ' +
            (scope.externalWhere || '1=1');
        };

        scope.$watch(
          'dossierFilterBtn.v',
          (v) => {
            scope.innerWhere = false;
            if(!v) { return; }
            if (v != 'filtregeo') {
              scope.innerWhere = "etat_dossier = '" + v + "'";
              setDataTableWhere();
            } else {
              const coll = scope.result.selectedDossiers;
              if(!coll || !coll.features.length) { return; }
              const feats = coll.features;
              const ids = feats
                .filter(feature => feature && feature.id)
                .map(feature => feature.id.split('.')[1])
                .join("','");
              scope.innerWhere = "IN ('" + ids + "')";
              setDataTableWhere();
            }
          },
          1
        );

        scope.$watch('externalDossierFilter', (edf) => {
          scope.externalWhere = false;
          if (angular.isDefined(edf)) {
            if (edf) {
              scope.externalWhere =
                "ref_dossier IN ('" + edf.join("','") + "')";
            }
            setDataTableWhere();
          }
        });
        scope.$watch('idsfilter', (edf) => {
          scope.externalWhere = false;
          if (angular.isDefined(edf)) {
            if (edf) {
              scope.externalWhere = " IN ('" + edf.join("','") + "')";
            }
            setDataTableWhere();
          }
        });

        scope.$watch('globalfilter', (edf) => {
          scope.externalWhere = false;
          if (angular.isDefined(edf)) {
            if (edf) {
              scope.externalWhere = edf;
            }
            setDataTableWhere();
          }
        });
        scope.result = {};
        scope.$watch('result.selectedDossiers', (coll) => {
          if (angular.isDefined(coll)) {
            if (scope.dossierFilterBtn.v !== 'filtregeo') {
              scope.dossierFilterBtn.v = 'filtregeo';
            } else {
              const feats = coll.features;
              if (feats) {
                const refs = [];
                const ids = [];
                for (let j = 0; j < feats.length; j++) {
                  let id = feats[j].id.split('.')[1];
                  ids.push(id);
                  refs.push(feats[j].properties.ref_dossier);
                }
                scope.innerWhere = false;
                scope.innerWhere = "IN ('" + ids.join("','") + "')";
                setDataTableWhere();
              }
            }
          }
        });

        /**
         * function passed to the datable to retrieve dossiers data
         * @param p
         * @returns {*}
         */
        scope.getReports = (p) => {
          let restrictedIds = filteredReportsIds.join(',');
          if (p) {
            scope.dataTableParams = p;
            if (p.force_restricted_ids) {
              restrictedIds = p.force_restricted_ids;
            }
          }
          let filtreControle = scope.reportTabs[scope.reportTabs.activeTab].key;

          // advanced filters
          if (filtreControle === 'advanced_filters') {
            filtreControle = 'tous';
          }

          scope.filtrecontrole = filtreControle;

          try {
            if (typeof ProgressionAndroid !== 'undefined') {
              ProgressionAndroid.showProgress();
            }
          } catch (e) {
            e.stack;
          }

          const promise = BacAppFactory.getdossiers(
            filtreControle,
            scope.dataTableParams.filter,
            scope.dataTableParams.crs,
            scope.dataTableParams.page,
            scope.dataTableParams.count,
            scope.dataTableParams.liaisonFilter,
            scope.dataTableParams.case_sensitive,
            scope.dataTableParams.sort,
            restrictedIds,
            scope.dataTableParams.isExport
          );
          promise.then((res) => {
            scope.reportsLength.v = parseInt(res.data.totalFeatures);
            scope.doss = res.data.features;

            try {
              if (typeof ProgressionAndroid !== 'undefined')
                ProgressionAndroid.hideProgress();
            } catch (e) {
              e.stack;
            }
          });
          return promise;
        };

        scope.sendDossiersResult = (result) => {
          BacAppFactory.sendResultBackDossiers(result);
        };

        scope.sendDossiersResult = (result) => {
          BacAppFactory.sendResultBackDossiers(result);
        };

        scope.selecteddossiers = { list: [] };

        scope.$watch('selecteddossiers.list', (l) => {
          scope.dossiersArchivables = 0;
          if (l) {
            for (let i in l) {
              if (l[i].properties.etat_dossier !== 'archive') {
                scope.dossiersArchivables++;
              }
            }
            scope.$emit('changeSelectedDossier', l);
            scope.res = l;
          }
        });

        scope.updateStatutDossiers = (statut) => {
          if (scope.selecteddossiers.list.length) {
            const ans = confirm(
              'Êtes-vous sur de vouloir modifier le statut des dossiers sélectionnés ?'
            );
            if (ans) {
              gaDomUtils.showLocalLoader('.currentPage');

              const toChange = scope.selecteddossiers.list.map((c) => {
                return c.id;
              });

              BacAppFactory.updatestatutdossiers(toChange, statut).then(() => {
                scope.dossiersArchivables = 0;
                gaDomUtils.hideGlobalLoader('.currentPage');
                scope.refreshReports();
              });
            }
          }
        };

        /*****************************
                 EDITION D'UN DOSSIER
                 ******************************/

        /**
         * setReferenceDossier
         */
        scope.setReferenceDossier = () => {
          if (BacAppFactory.appCfg.main.dossierCfg.numerotation.auto) {
            scope.saveReport(BacAppFactory.getNumeroAuto('TMP_KIS_DOSSIER_ID'));
          }
        };

        /**
         * notifyLinkCopy
         */
        scope.notifyLinkCopy = (type) => {
          require('toastr').success(
            "Lien d'accès direct à ce " +
              type +
              ' copié dans votre presse-papiers.',
            '',
            {
              positionClass: 'toast-bottom-left',
            }
          );
        };

        let initCopyReportButton = false;
        let reportDialog;

        scope.getCopyControleUrl = () => {
          if ($location.search().fid) $location.search('fid', null);
          return $location.absUrl() + '&fid=' + scope.currentControle.id;
        };

        scope.$on('bac_open_dossier', (event, data) => {
          if (angular.isDefined(data)) {
            BacAppFactory.getdossier(data[0].id).then((res) => {
              scope.editReport(res.data.features[0]);
            });
          }
        });

        scope.$on('bac_open_controle', (event, data) => {
          if (angular.isDefined(data)) {
            gaDomUtils.showGlobalLoader();
            BacAppFactory.getdossier(data[0].dossier_id).then((res) => {
              gaDomUtils.hideGlobalLoader();
              scope.editReport(
                res.data.features[0],
                false,
                data[0].controle_id
              );
            });
          }
        });

        let refreshHistoriqueTableAntibes = (idx) => {
          scope.ftiHistorique.forEach((fti, index) => {
            const histoBranch = {
              label: fti.alias,
              template:
                'js/XG/widgets/bacapp/main/views/modals/modal.report.historique.details.html',
              ftiToShow: fti,
              activeView: false,
            };

            if (angular.isUndefined(scope.reportTree[idx].children)) {
              scope.reportTree[idx].children = [];
              scope.reportTree[idx].children.push(histoBranch);
            } else {
              scope.reportTree[idx].children.push(histoBranch);
            }
          });
        };
        /**
         * Changement en masse du statut des dossiers
         */
        let dossierStatutDialog;
        let preUpdateStatutDialog;

        let filesToUpdateData = [];

        scope.changeStatutDossiersEnMasse = (dossier) => {
          scope.multiDossiersUpdate = false;
          filesToUpdateData = [];
          if (!dossier) {
            filesToUpdateData = scope.res;
            dossier = scope.res[0];
            scope.multiDossiersUpdate = filesToUpdateData.length > 1;
          } else {
            filesToUpdateData.push(dossier);
          }

          scope.reportData = angular.copy(dossier);
          scope.apptype = 'bac';
          scope.newDossierStatut = {
            date_raccordement: $filter('date')(
              new Date(),
              'yyyy-MM-ddTHH:mm:ss.sssZ'
            ),
          };
          dossierStatutDialog = ngDialog.open({
            template:
              'js/XG/widgets/ancapp/main/views/modals/modal.report.statut.html',
            className: 'ngdialog-theme-plain width800 nopadding miniclose',
            closeByDocument: false,
            scope: scope,
            preCloseCallback: (closeFromUpdateStatus)=>{
              if(closeFromUpdateStatus){
                scope.res.length = 0;
              }
            }
          });
        };
        /**
         * update le statut du dossier apres confirmation
         */

        scope.pre_updateDossierStatut = () => {
          scope.newReference = false;
          scope.reference = {};
          scope.dossiersToUpdate = [];

          (filesToUpdateData || []).forEach((dossier) => {
            const dossierToPush = angular.copy(dossier);
            dossierToPush.nomDossierBac = dossierToPush.properties.ref_dossier;
            scope.dossiersToUpdate.push(dossierToPush);
          });
          preUpdateStatutDialog = ngDialog.open({
            template:
              'js/XG/widgets/ancapp/main/views/modals/modal.report.statut.confirm.html',
            className:
              'ngdialog-theme-plain width600 nopadding miniclose error_dialog',
            closeByDocument: false,
            scope: scope,
          });
        };
        /**
         * updateDossiersStatut
         */
        scope.updateDossiersStatut = () => {
          let dossiersIds = (scope.dossiersToUpdate || []).map(
            (dossier) => dossier.id
          );
          let dossiersWithoutControls = [];
          let dossiersEncours = [];
          if (scope.newDossierStatut.etat_dossier === 'en_cours') {
            scope.dossiersToUpdate.forEach((element) => {
              if (angular.equals(element.properties.dernierControle, {})
                && (!element.properties.prochain_controle
                  || element.properties.prochain_controle === '')) {
                dossiersWithoutControls.push(element.id);
              } else {
                dossiersEncours.push(element.id);
              }
            });
            dossiersIds = dossiersEncours.join(',');
          }
          BacAppFactory.updatestatutdossiers(
            dossiersIds,
            scope.newDossierStatut.etat_dossier
          )
            .then(() => {
            if (dossiersIds.length > 0) {
              require('toastr').success(
                'Etat des dossiers changé pour "' +
                  $filter('translate')(
                    'ancapp.report.status.' +
                      scope.newDossierStatut.etat_dossier
                  ) +
                  '"',
                '',
                { positionClass: 'toast-bottom-left' }
              )
                  }}
            )
            .then(() => {
              if (dossiersWithoutControls.length > 0) {
                return BacAppFactory.updatestatutdossiers(
                  dossiersWithoutControls.join(','),
                  'ouvert'
                ).then(() =>
                  require('toastr').success(
                    'Etat des dossiers changé pour "' +
                      $filter('translate')('ancapp.report.status.ouvert') +
                      '"',
                    '',
                    { positionClass: 'toast-bottom-left' }
                  )
                );
              }
              return;
            })
            .then(() => {
              preUpdateStatutDialog.close();
              dossierStatutDialog.close(true);
              scope.refreshReports(0);
            })
            .catch(() =>
              require('toastr').error(
                "Le changement de l'état des dossiers a échoué",
                '',
                { positionClass: 'toast-bottom-left' }
              )
            );
        };

        let selectParcelleModal;
        let openDialogSelectParcelle = (type) => {
          scope.parcelleToShowOnDialog = type;

          scope.selectedParcelle = {};
          selectParcelleModal = ngDialog.open({
            template:
              'js/XG/widgets/bacapp/main/views/modals/modal.select_parcelle.html',
            className: 'ngdialog-theme-plain width350 miniclose nopadding',
            closeByDocument: false,
            scope: scope,
          });
        };

        scope.chooseParcelle = () => {
          selectParcelleModal.close();
          if (angular.isDefined(scope.selectedParcelle.index))
            scope.sectionOrParcelle =
              scope.columnName +
              " LIKE '%" +
              scope.currentReport.properties[scope.parcelleToShowOnDialog][
                scope.selectedParcelle.index
              ].section +
              "%'";
        };

        scope.filterOnSectionOrNumParcelle = () => {
          if (
            angular.isDefined(scope.currentBranch.ftiToShow.name) &&
            angular.isDefined(scope.appCfgProperties.configHistorique)
          ) {
            angular
              .copy(scope.appCfgProperties.configHistorique)
              .forEach((config, i) => {
                if (config.name === scope.currentBranch.ftiToShow.name) {
                  scope.columnName =
                    scope.appCfgProperties.configHistorique[i].attribut;
                }
              });
          } else {
            require('toastr').error(
              "Aucune configuration sur la colonne à filtrer n'est définie."
            );
          }

          if (
            angular.isDefined(
              scope.currentReport.properties.parcelleHabitation
            ) &&
            scope.currentReport.properties.parcelleHabitation.length === 1
          ) {
            scope.sectionOrParcelle =
              scope.columnName +
              " LIKE '%" +
              scope.currentReport.properties.parcelleHabitation.section +
              "%'";
          } else if (
            angular.isDefined(scope.currentReport.properties.parcelleFiliere) &&
            scope.currentReport.properties.parcelleFiliere.length === 1
          ) {
            scope.sectionOrParcelle =
              scope.columnName +
              " LIKE '%" +
              scope.currentReport.properties.parcelleFiliere.section +
              "%'";
          } else if (
            angular.isDefined(
              scope.currentReport.properties.parcelleHabitation
            ) &&
            scope.currentReport.properties.parcelleHabitation.length > 1
          ) {
            openDialogSelectParcelle('parcelleHabitation');
          } else if (
            angular.isDefined(scope.currentReport.properties.parcelleFiliere) &&
            scope.currentReport.properties.parcelleFiliere.length > 1
          ) {
            openDialogSelectParcelle('parcelleFiliere');
          } else {
            require('toastr').error('Aucune parcelle associée au dossier.');
          }
        };

        scope.resetFilterSection = () => {
          if (angular.isDefined(scope.sectionOrParcelle)) {
            delete scope.sectionOrParcelle;
            $rootScope.$broadcast('refreshDatatable', {
              uid: scope.currentBranch.ftiToShow.uid,
            });
          }
        };

        /**
         * create new report
         */
        scope.editReport = (
          report,
          geometry,
          controleId,
          SuppOptions,
          FromAndroid,
          id_dossier
        ) => {
          try {
            if (typeof ProgressionAndroid !== undefined)
              ProgressionAndroid.showProgress();
          } catch (e) {
            e.stack;
          }

          if (
            typeof AppAndroid !== 'undefined' &&
            typeof ancAppAndroid !== 'undefined'
          ) {
            try {
              if (typeof AppAndroid !== 'undefined') AppAndroid.adjustBar(true);
            } catch (e) {
              e.stack;
            }

            AppAndroid.setReportOpened(true);

          }

          if ((id_dossier == undefined) && (report != undefined)) {
            id_dossier = report.id;
          }
          //update dossier to avoid issues in widget bac
          //we need to update geographic data to fit BAC's srid
          BacAppFactory.getdossier(id_dossier).then((res) => {
            if (res.data && res.data.features && res.data.features.length > 0) {
              try {
                if (reportDialog) reportDialog.close();
              } catch (e) {
                console.error("error closing dossier: " + e.message);
              }
              report = res.data.features[0];
            } else {
              console.error("error getDossier(id_dossier) with id_dossier = " + id_dossier);
            }
            editReportComplete(
              report,
              geometry,
              controleId,
              SuppOptions,
              FromAndroid,
              id_dossier
            );
          });
        };

        scope.newFromMap = false;
        let editReportComplete = function (
          report,
          geometry,
          controleId,
          suppOptions,
          FromAndroid,
          id_dossier,
          fromMap
        ) {
          scope.newFiliereElement = {};
          scope.currentFilieres = undefined;
          scope.currentControles = undefined;
          scope.currentFiliere = {};
          scope.currentControle = {};

          scope.tournee = { concerne: false };

          // default
          if (!report) {
            report = {
              type: 'Feature',
              properties: {
                ref_dossier: '',
                etat_dossier: 'ouvert',
                proprietaires: [],
                locataires: [],
                parcelleHabitation: [],
                parcelleFiliere: [],
              },
            };

            if (geometry) {
              report.geometry = geometry;
            }

            //Emprise depuis ANC MAP WIDGET, récupération des informations de l'adresse puis injection dans le formulaire
            if (suppOptions) {
              Object.keys(suppOptions).forEach((c) => {
                if (~c.indexOf('housenumber')) {
                  report.properties.adresse_num_rue = parseInt(
                    suppOptions[c],
                    10
                  );
                }
                if (~c.indexOf('street')) {
                  report.properties.adresse_rue = suppOptions[c];
                }
                if (~c.indexOf('city') && c !== 'citycode') {
                  report.properties.adresse_ville = suppOptions[c];

                  // alerte si ville pas connue
                  let villeCorrespondance = suppOptions[c];
                  if (angular.isDefined(listeDesVillesActives) && listeDesVillesActives.length) {
                    const hits = listeDesVillesActives.filter((x) => {
                      return (
                        x.value.toLowerCase() === suppOptions[c].toLowerCase()
                      );
                    });
                    // aucune correspondance directe (lowercase)
                    if (!hits.length) {
                      //  tentative avec levenshtein
                      const hitsLev = listeDesVillesActives
                        .filter((x) => {
                          x.lev = gaJsUtils.levenshtein(
                            x.value,
                            suppOptions[c]
                          );
                          return x.lev > 0.6;
                        })
                        .sort((a, b) => {
                          return a.lev > b.lev ? -1 : b.lev > a.lev ? 1 : 0;
                        });

                      // rien > 0.6 avec levenshtein
                      if (!hitsLev.length) {
                        require('toastr').error(
                          "Aucune correspondance avec une commune gérée par le SPANC n'a pu être établie avec la commune <b> " +
                            suppOptions[c] +
                            '</b>.',
                          'Attention',
                          {
                            closeButton: true,
                            timeOut: '0',
                            extendedTimeOut: '0',
                          }
                        );
                        villeCorrespondance = null;
                      } else {
                        require('toastr').warning(
                          "Aucune correspondance directe avec une commune gérée par le SPANC n'a pu être établie avec la commune <b> " +
                            suppOptions[c] +
                            '.</b><br/><br/>' +
                            'Cependant la commune <b>' +
                            hitsLev[0].value +
                            '</b> semble correspondre et a été sélectionnée.',
                          'Information',
                          {
                            closeButton: true,
                            timeOut: '0',
                            extendedTimeOut: '0',
                          }
                        );
                        villeCorrespondance = hitsLev[0].value;
                        if (hitsLev[0].cp.length) {
                          report.properties.adresse_cp = hitsLev[0].cp[0];
                        }
                      }
                    } else {
                      villeCorrespondance = hits[0].value;
                      if (hits[0].cp.length) {
                        report.properties.adresse_cp = hits[0].cp[0];
                      }
                    }
                  }
                  report.properties.adresse_ville = villeCorrespondance;
                }

                if (~c.indexOf('country')) {
                  report.properties.adresse_pays = suppOptions[c];
                }
              });
            }

            scope.currentReportTitle = 'Nouveau Dossier';
            dateUtils.convertAllDatesToDateString(
              report.properties,
              dossierDateNames
            );
            scope.currentReport = report;

            if (fromMap) {
              scope.currentReport.newFromMap = true;
            }

            scope.currentReport.properties.date_creation = new Date();
            setDossierDatesFormat(report.properties);
            scope.setReferenceDossier();
          } else {
            if (report.properties.tournee === true) {
              scope.tournee = {
                concerne: true,
                par: report.properties.tournee_par,
                pour: report.properties.tournee_pour,
              };
            }

            setDossierDatesFormat(report.properties);

            if (report.geometry && typeof report.geometry == 'string') {
              console.log(report.geometry);
              report.geometry = JSON.parse(report.geometry);
            }

            scope.currentReportTitle = $sce.trustAsHtml(
              ancBacTools.setDossierFullname(
                report,
                'bac',
                initCopyReportButton,
                $location
              )
            );
            dateUtils.convertAllDatesToDateString(
              report.properties,
              dossierDateNames
            );
            scope.currentReport = report;
          }

          reportDialog = ngDialog.open({
            template:
              'js/XG/widgets/bacapp/main/views/modals/modal.report.html',
            className: 'ngdialog-theme-plain fullScreen nopadding miniclose',
            closeByDocument: false,
            scope: scope,
            preCloseCallback: () => {
              if (typeof AppAndroid !== 'undefined') {
                try {
                  if (typeof AppAndroid !== 'undefined') {
                    AppAndroid.adjustBar(false);
                    AppAndroid.setReportOpened(false);
                  }
                } catch (e) {
                  e.stack;
                }
              }
            },
          });
          if (typeof ancAppAndroid !== 'undefined')
            scope.reportDialogForAndroid = reportDialog;

          // collapse and select first branch when dialog is opened
          let deregOpenReportDialog = $rootScope.$on(
            'ngDialog.opened',
            (e, $dialog) => {
              if (reportDialog.id === $dialog.attr('id')) {
                $timeout(() => {
                  setDossierArborescence(controleId, undefined);
                  scope.reportTreeControl.reset_rows();
                  scope.reportTreeControl.collapse_all();
                  scope.reportTreeControl.select_first_branch();

                  deregOpenReportDialog();
                });
              }
            }
          );

          refreshDossierActions();

          try {
            if (typeof ProgressionAndroid !== undefined)
              ProgressionAndroid.hideProgress();
          } catch (e) {
            e.stack;
          }
        };

        $rootScope.$on('ngDialog.closed', (e, $dialog) => {
          if (
            reportDialog &&
            reportDialog.id &&
            reportDialog.id === $dialog.attr('id')
          ) {
            $timeout(function () {
              scope.reportTreeControl.reset_rows();
              scope.reportTreeControl.collapse_all();
              scope.reportTreeControl.select_first_branch();
              if ($location.search().fid) {
                $location.search('fid', null);
              }
            });
          }
        });

        if (
          typeof AppAndroid !== 'undefined' ||
          scope.idsfilter ||
          scope.globalfilter
        ) {
          scope.datatableDossiersCrud = {
            update: { func: scope.editReport },
            remove: false,
          };
        } else {
          scope.datatableDossiersCrud = {
            create: { func: scope.editReport },
            update: { func: scope.editReport },
            remove: true,
          };
        }
        const documentsDossierBranchLabel = 'Documents du dossier';
        let initReportTree;
        if (typeof AppAndroid === 'undefined') {
          initReportTree = [
            {
              label: 'Informations générales',
              identifier: 'info_generales',
              template:
                'js/XG/widgets/bacapp/main/views/modals/modal.report.general.html',
              isMainBranch: true,
              classes: [],
              key: 'general',
            },
            {
              label: "Demandes d'urbanisme",
              template:
                'js/XG/widgets/bacapp/main/views/modals/modal.report.urbanisme.liste.html',
              classes: ['hiddenTreeBranch'],
              key: 'demandes_urba',
            },
            {
              label: 'Cartographie des Branchements',
              template:
                'js/XG/widgets/bacapp/main/views/modals/modal.report.branchement.html',
              classes: ['hiddenTreeBranch'],
              isBranchement: true,
              key: 'branchements',
            },
            {
              label: 'Instructions',
              template:
                'js/XG/widgets/bacapp/main/views/modals/modal.report.controles.liste.html',
              classes: ['hiddenTreeBranch'],
              key: 'instructions',
            },
            {
              label: 'Documents du dossier',
              template:
                'js/XG/widgets/ancapp/main/views/modals/modal.report.dossier.html',
              classes: ['hiddenTreeBranch'],
              key: 'documents_dossier',
            },
          ];
        } else {
          initReportTree = [
            {
              label: 'Informations générales',
              identifier: 'info_generales',
              template:
                'js/XG/widgets/bacapp/main/views/modals/modal.report.general.html',
              isMainBranch: true,
              classes: [],
              key: 'general',
            },
            {
              label: 'Instructions',
              template:
                'js/XG/widgets/bacapp/main/views/modals/modal.report.controles.liste.html',
              classes: ['hiddenTreeBranch'],
              key: 'instructions',
            },
            {
              label: 'Documents du dossier',
              template:
                'js/XG/widgets/ancapp/main/views/modals/modal.report.dossier.html',
              classes: ['hiddenTreeBranch'],
              key: 'documents_dossier',
            },
          ];
        }

        // set visibility and label
        if (angular.isDefined(scope.appCfgProperties.branchToShow)) {
          initReportTree.forEach((b) => {
            const cfg = scope.appCfgProperties.branchToShow[b.key];
            if (angular.isDefined(cfg)) {
              if (cfg.visible === false) b.classes = ['hideBranchBac'];
              if (cfg.label) b.label = cfg.label;
            }
          });
        }

        // set tree
        scope.reportTree = initReportTree;

        // onglet des informations du dossier
        const baseTabs = (scope.dossierInfosSupTabs = [
          { title: 'Données générales' },
          { title: 'Données techniques' },
        ]);
        scope.dossierInfosSupTabs.activeTab = 0;
        scope.$watch(
          'dossierInfosSupTabs.activeTab',
          (i) => {
            if (i < 0) {
              scope.dossierInfosSupTabs.activeTab = 0;
            }
          },
          1
        );

        // informations supplémentaires si presence d'attributs prefixes par extra_
        // dans le fti kis_anc_dossier
        if (scope.dossierFti != undefined && Array.isArray(scope.dossierFti.attributes)) {
          scope.dossierInfosSup = scope.dossierFti.attributes.filter((x) => {
            return x.name.indexOf('extra_') === 0;
          });
          if (scope.dossierInfosSup.length) {
            scope.dossierInfosSupTabs.push({
              title: 'Données supplémentaires',
            });
          }
        }

        if (typeof AppAndroid === 'undefined') {
          scope.reportTree.push({
            label: 'Tâches associées aux instructions',
            template:
              'js/XG/widgets/ancapp/main/views/modals/modal.report.tasks.html',
            classes: ['hiddenTreeBranch'],
          });
          scope.reportTree.push({
            label: 'Rendez-vous',
            template:
              'js/XG/widgets/ancapp/main/views/modals/modal.report.evenement.html',
            classes: ['hiddenTreeBranch'],
          });
          scope.reportTree.push({
            label: 'Historique des actions',
            template:
              'js/XG/widgets/ancapp/main/views/modals/modal.report.history.html',
            classes: ['hiddenTreeBranch'],
          });
        }

        // Informations supplémentaires si présence de feature préfixées par historique_
        scope.ftiHistorique = [];
        FeatureTypeFactory.resources.featuretypes.forEach((fti) => {
          if (fti.name.indexOf('historique_') === 0) {
            scope.ftiHistorique.push(fti);
          }
        });

        if (scope.ftiHistorique.length) {
          scope.reportTree.push({
            label: 'Historique',
            template:
              'js/XG/widgets/bacapp/main/views/modals/modal.report.historique.html',
            to_hide: false,
            classes: [],
          });

          scope.reportTree.forEach((branch, i) => {
            if (branch.label === 'Historique') scope.historiqueBranchIndex = i;
          });
          refreshHistoriqueTableAntibes(scope.historiqueBranchIndex);
        }

        // le controle a été modifié il faut donc proposer de le sauvegarder si on change d'onglet
        scope.$on('ancCtrlFormIsDirty', (v, i) => {
          scope.ctrlFormIsDirty = 1;
        });
        scope.$on('ancControleDemandeurChoisi', (v, data) => {
          scope.currentControle.properties.id_demandeur = data.demandeur.id;
          console.log(scope.currentControle);
        });

        scope.$on('ancControleDemandeurReset', (v, data) => {
          scope.currentControle.properties.id_demandeur = null;
        });

        scope.reopenedControle = false;
        /**
         * reopenControle
         * permet de reouvrir temporaire un controle
         */
        scope.reopenControle = () => {
          scope.reopenedControle = true;
          $rootScope.$broadcast('reopenControle');
        };
        /**
         * actionAvantChangementBranche
         */

        scope.actionAvantChangementBranche = (branch) => {
          let def = $q.defer();

          scope.$broadcast('checkDirty', scope.checkDiffCdata, scope.cdata);

          // previous branch
          if (
            angular.isDefined(scope.currentBranch) &&
            angular.isDefined(branch)
          ) {
            if (
              scope.currentBranch.template ===
              'js/XG/widgets/bacapp/main/views/modals/modal.report.historique.details.html'
            ) {
              scope.currentBranch.activeView = false;
              if (angular.isDefined(scope.sectionOrParcelle)) {
                delete scope.sectionOrParcelle;
              }
            }
            // previous branch was a controle
            if (scope.currentBranch.isCtrlForm && scope.ctrlFormIsDirty) {
              let ans = confirm(
                "Enregistrer les modifications apportées à l'instruction en cours ?"
              );
              if (!ans) {
                def.resolve();
              } else {
                scope.saveControleDetail(1).then(
                  () => {
                    def.resolve();
                  },
                  () => {
                    def.reject();
                  }
                );
              }
            } else {
              def.resolve();
            }

            if (scope.currentBranch.key === 'documents_dossier') {
              scope.documentsCheckedForMail = [];
            }
          } else {
            def.resolve();
          }

          if (angular.isDefined(scope.controleCommentConfig)) {
            delete scope.controleCommentConfig;
          }

          return def.promise;
        };

        scope.transformLoginIfNeeded = (controle) => {
          let name;
          let noNeedToTransform = 1;
          for (let i = 0; i < userslist.length; i++) {
            if (controle.properties.agent === userslist[i].login) {
              name = userslist[i].name + ' ' + userslist[i].vorname;
              noNeedToTransform = 0;
              return name;
            }
          }

          if (noNeedToTransform === 1) {
            return controle.properties.agent;
          }
        };

        scope.reportTreeControl = {};
        scope.controleCommentConfig = {};

        let getBranchementsData = () => {
          // retrieve map objects
          scope.branchementsDossier = 0;
          return QueryFactory.data(
            dossierBranchementFti.uid,
            "id_dossier='" + scope.currentReport.id + "'"
          ).then((res) => {
            scope.branchementsDossier = res.data;
            console.log(scope.branchementsDossier);
          });
        };

        /**
                 picking a branch
                 */
        scope.reportTree_handle = (branch) => {
          if (scope.ftiHistorique.length) {
            scope.reportTreeControl.expand_branch(
              scope.reportTree[scope.historiqueIndex]
            );
          }

          scope.currentBranch = branch;

          if (
            scope.currentBranch.template ===
              'js/XG/widgets/bacapp/main/views/modals/modal.report.historique.details.html' &&
            angular.isDefined(scope.currentBranch.activeView)
          )
            scope.currentBranch.activeView = true;

          scope.ctrlFormIsDirty = false;
          scope.reopenedControle = false;

          if (branch.isBranchement) {
            getBranchementsData();
          }

          if (typeof AppAndroid !== 'undefined') {
            // wtf on est dans BAC ?
            if (
              branch &&
              branch.template ===
                'js/XG/widgets/ancapp/main/views/modals/modal.report.filiere.html'
            ) {
              AppAndroid.setAppName('DOSSIER');
              AppAndroid.setLastAppName('DOSSIER');
            } else {
              AppAndroid.setAppName('OTHER');
              AppAndroid.setLastAppName('OTHER');
            }
          }

          if (branch.hasOwnProperty('controleId')) {
            // attachment du controle
            scope.controleAttachmentData = {
              id: branch.controleId,
              featuretype: 'kis_bac_dossier_controle',
            };

            scope.typeControle = branch.typeControle;
            scope.currentControles.forEach((c) => {
              if (c.id === branch.controleId) {
                scope.currentControle = c;

                // retrieve data

                scope.cdata = {
                  general: {
                    // date_passage: $filter('date')(new Date(), "yyyy-MM-ddTHH:mm:ss.sssZ")
                  },
                  conformite: {},
                };
                gaDomUtils.showLocalLoader('.currentPage');
                BacAppFactory.getcontroledetail(
                  scope.currentReport.id,
                  c.id
                ).then((res) => {
                  if (res.data !== '') {
                    scope.cdata = res.data;
                    scope.checkDiffCdata = angular.copy(scope.cdata);
                  }

                  $timeout(() => {
                    gaDomUtils.removeLocalLoader('.currentPage');
                  }, 500);
                });
                scope.reportTreeControl.expand_branch(branch);
              }
            });

            const controleName = scope.currentControle.properties.type;

            if (angular.isDefined(scope.allCtrlConfig[controleName]))
              scope.controleCommentConfig = scope.allCtrlConfig[controleName];
            else scope.controleCommentConfig = {};
          }

          if (branch.hasOwnProperty('demandeUrbanismeId')) {
            scope.currentDemandeUrbanismes.forEach((f) => {
              if (f.id === branch.demandeUrbanismeId) {
                scope.currentDemandeUrbanisme = f;
                console.log(scope.currentDemandeUrbanisme);

                BacAppFactory.getcaracteristiqueconstruction(
                  scope.currentDemandeUrbanisme.id
                ).then((res) => {
                  console.log(res.data);
                  if (res.data.features.length) {
                    res.data.features.forEach((o) => {
                      scope.caracteristiquesdesconstructions.push(o.properties);
                    });
                  } else {
                    scope.caracteristiquesdesconstructions = [];
                  }
                });
              }
            });
            scope.reportTreeControl.expand_branch(branch);
          }

          if (branch.label.startsWith(documentsDossierBranchLabel)) {
            scope.fillDossierAttachmentsTab();
          }
        };

        scope.fillDossierAttachmentsTab = () => {
          scope.documentLiesTousTabs = [
            {
              title:
                'Dossier (' + scope.dossierAttachmentData.attachmentsNo + ')',
              key: 'dossier',
              content:
                'js/XG/widgets/ancapp/main/views/modals/modal.report.dossier.documents_dossier.html',
            },
            {
              title: 'Instructions',
              key: 'controles',
              content:
                'js/XG/widgets/ancapp/main/views/modals/modal.report.dossier.documents_controles.html',
            },
          ];
          scope.documentLiesTousTabs.activeTab = 0;

          $rootScope.countWhichTab = 0;

          scope.updateAllTabsLabels();
        };

        /**
         * getFeatureAliasFromUid
         * @param uid
         * @returns {*}
         */
        scope.getFeatureAliasFromUid = (uid) => {
          const ft = FeatureTypeFactory.getFeatureByUid(uid);
          return ft.alias;
        };

        /**
         * refresh la liste des controles qui apparaissent dans le dossier
         * refreshListeControles
         * @param controleId
         */
        let refreshListeControles = (controleId) => {
          // get controles
          BacAppFactory.getcontroles(scope.currentReport.id).then((res) => {
            // sort by etat and then id
            let tmp = gaJsUtils
              .sortByFeatureProperty(res.data.features, 'date_saisie_controle')
              .reverse();

            scope.currentControles = tmp;

            setDefaultControleAgent();
            scope.ctrlTaskTabs = [];
            scope.ctrlTaskTabs.activeTab = 0;
            scope.reportTree[ctrlBranchIndex].children = [];
            // need to reset it
            scope.listCtrlFiliereDocumentsLies.controles = [];

            scope.currentControles.forEach((c) => {
              let ctrlLabel;
              if (c.properties.type === 'DUB' || c.properties.type === 'DAU')
                ctrlLabel = BacAppFactory.getControleName(
                  c.properties.type,
                  c.properties.ref_demande_autorisation_urbanisme
                );
              else
                ctrlLabel = BacAppFactory.getControleName(
                  c.properties.type,
                  c.properties.date_passage
                );
              if (
                ancBacTools.getCurrentDossierAttachmentsInfos(
                  scope.doss,
                  scope.currentReport
                ) != null
              ) {
                let attachmentInfo = ancBacTools.getCurrentDossierAttachmentsInfos(
                  scope.doss,
                  scope.currentReport
                );
                if (attachmentInfo && !attachmentInfo.controlesAttachments) {
                  attachmentInfo.controlesAttachments = [];
                }
                c.attachmentsNo = attachmentInfo.controlesAttachments[c.id];
              }
              ctrlLabel;
              c.attachmentsNo = getControleAttachmentNo(
                scope.doss,
                scope.currentReport,
                c.id
              );

              let ctrlBranch = {
                label: ctrlLabel,
                template:
                  'js/XG/widgets/bacapp/main/views/modals/modal.report.controle.html',
                controleId: c.id,
                isCtrlForm: true,
                classes:
                  c.properties.etat === 'ouvert' ? [] : ['inactiveTreeBranch'],
                children: [
                  {
                    label: 'Documents liés (' + c.attachmentsNo + ')',
                    template:
                      'js/XG/widgets/ancapp/main/views/modals/modal.report.controle.documents_types.html',
                    typeControle: c.properties.type,
                    controleId: c.id,
                  },
                ],
              };

              // set in tree
              scope.reportTree[ctrlBranchIndex].children.push(ctrlBranch);
              scope.reportTreeControl.expand_branch(
                scope.reportTree[ctrlBranchIndex]
              );

              if (controleId && controleId === c.id) {
                scope.reportTreeControl.select_branch(ctrlBranch);
              }

              scope.ctrlTaskTabs.push({
                title: ctrlLabel,
                content:
                  'js/XG/widgets/ancapp/main/views/modals/modal.report.ctrltask.html',
                uid: controleFti.uid,
                id: c.id,
              });

              let toPushControl = {
                label:
                  ctrlLabel +
                  (c.properties.etat === 'ouvert'
                    ? ' (instruction en cours)'
                    : ''),
                attachmentData: {
                  id: c.id,
                  featuretype: 'kis_bac_dossier_controle',
                  feature: c,
                },
              };
              scope.listCtrlFiliereDocumentsLies.controles.push(toPushControl);
              if (c.properties.etat === 'ouvert') {
                scope.currentCtrlShowFiles = toPushControl;
              }
            });
          });
        };

        let getControleAttachmentNo = (dossier, currentReport, id) => {
          let currentInstructionAttNo = 0;
          let dossierAttachmentsInfos = ancBacTools.getCurrentDossierAttachmentsInfos(
            dossier,
            currentReport
          );
          if (dossierAttachmentsInfos !== null) {
            if (
              dossierAttachmentsInfos.controlesAttachments &&
              typeof dossierAttachmentsInfos.controlesAttachments === typeof {}
            ) {
              if (
                dossierAttachmentsInfos.controlesAttachments.hasOwnProperty(id)
              ) {
                currentInstructionAttNo =
                  dossierAttachmentsInfos.controlesAttachments[id];
              }
            }
          }
          return currentInstructionAttNo;
        };

        /**
         * traverseAndReplaceListeDeroulantes
         * @param {*} o
         * @param {*} toReplace
         * @param {*} prevKey
         */
        function traverseAndReplaceListeDeroulantes(o, toReplace, prevKey) {
          for (let i in o) {
            if (!!o[i] && typeof o[i] == 'object') {
              traverseAndReplaceListeDeroulantes(
                o[i],
                toReplace,
                prevKey + (prevKey === '' ? '' : '.') + i
              );
            } else {
              const ftiAttributeName = distinctFtiAttributeControlNameMap.has(i)
                ? distinctFtiAttributeControlNameMap.get(i)
                : i;
              if (
                angular.isDefined(toReplace) &&
                angular.isDefined(toReplace[ftiAttributeName]) &&
                toReplace[ftiAttributeName].hasOwnProperty(o[i]) // correction kis-2948
              ) {
                let newValue = toReplace[ftiAttributeName][o[i]];
                o[i] = newValue === undefined ? '' : newValue;
              }
            }
          }
        }

        /**
         * A l'ouverture d'une instruction de type 'conformité',
         * Pour chaque contrôle ayant des attributs 'setAttr' et 'attname' distints
         * On définit une clé/valeur {setAttr,attname}
         * @see formField.js#replaceAttName()
         */
        const distinctFtiAttributeControlNameMap = new Map();
        $rootScope.$on('differenceBetweenSetAttrAndAttName', (event, data) => {
          distinctFtiAttributeControlNameMap.set(data.setAttr, data.attname);
        });

        let getDomaineRestriction = (fti) => {
          let keyvals = {};
          fti.attributes.forEach((att) => {
            if (
              att.name !== 'civilite' &&
              angular.isDefined(att.restrictions) &&
              att.restrictions.length
            ) {
              keyvals[att.name] = att.restrictions[0].listofValues;
            }
          });
          return keyvals;
        };

        /**
         * transformDataForDocxGeneration
         * @param data
         * @returns {*}
         */
        let transformDataForDocxGeneration = (data) => {
          const def = $q.defer();
          const obj = angular.copy(data);

          // transformation des cles valeurs des listes déroulantes
          const listeDeroulantes = FeatureTypeFactory.getFeatureByNameAndDatastore(
            BacAppFactory.appCfg.main.datastore,
            'kis_bac_listes_deroulantes_controles'
          );
          if (listeDeroulantes) {
            let keyvals = {};
            listeDeroulantes.attributes.forEach((att) => {
              if (
                att.name !== 'civilite' &&
                angular.isDefined(att.restrictions) &&
                att.restrictions.length
              ) {
                keyvals[att.name] = att.restrictions[0].listofValues;
              }
            });
            traverseAndReplaceListeDeroulantes(obj, keyvals, '');
          }

          // transformation de la date pour affichage
          if (obj.datesDossier && Object.keys(obj.datesDossier).length > 0) {
            for (let x in obj.datesDossier) {
              obj.datesDossier[x] = moment(obj.datesDossier[x]).format(
                'DD-MM-YYYY'
              );
            }
          }

          // pour le cas de la DRAAC on met aussi en forme les autres dates
          // @TODO a uniformiser
          if (
            gaJsUtils.checkNestedProperty(
              'info_ass_coll.certif_conform.date',
              obj
            )
          ) {
            obj.info_ass_coll.certif_conform.date = moment(
              obj.info_ass_coll.certif_conform.date
            ).format('DD-MM-YYYY');
            //console.log(obj.info_ass_coll.certif_conform.date);
          }
          if (
            gaJsUtils.checkNestedProperty(
              'info_ass_coll.autorisation_racc.date',
              obj
            )
          ) {
            obj.info_ass_coll.autorisation_racc.date = moment(
              obj.info_ass_coll.autorisation_racc.date
            ).format('DD-MM-YYYY');
          }

             obj.prochain_controle_preconise = {
            type_prochain_controle_preconise:
              scope.currentControle.properties.type_prochain_controle_preconise,
            date_prochain_controle_preconise: scope.currentControle.properties
              .date_prochain_controle_preconise
              ? $filter('date')(
                  scope.currentControle.properties
                    .date_prochain_controle_preconise,
                  'dd/MM/yyyy'
                )
              : '',
          };
          obj.infos_spanc = BacAppFactory.appCfg.main.infosSpanc;
          obj.dossier = scope.currentReport.properties;
          if (scope.dossierFti) {
            let keyvals = getDomaineRestriction(scope.dossierFti);
            traverseAndReplaceListeDeroulantes(obj, keyvals, '');
          }
          // lib type de controle
          obj.controle_type = BacAppFactory.getControleName(
            scope.currentControle.properties.type
          );
          obj.avis = scope.currentControle.properties.avis;

          if (
            scope.currentReport.properties.proprietaires !== undefined &&
            scope.currentReport.properties.proprietaires[0] !== undefined
          ) {
            obj.proprietaire = scope.currentReport.properties.proprietaires[0];
          }
          if (
            scope.currentReport.properties.locataires !== undefined &&
            scope.currentReport.properties.locataires[0] !== undefined
          ) {
            obj.proprietaire = scope.currentReport.properties.locataires[0];
          }
          scope.demandeUrbaFti = FeatureTypeFactory.getFeatureByNameAndDatastore(
            BacAppFactory.appCfg.main.datastore,
            'kis_bac_demande_autorisation_urbanisme'
          );
          let parccelle = '';
          if (
            scope.currentReport.properties.parcelleHabitation !== undefined &&
            scope.currentReport.properties.parcelleHabitation[0] !== undefined
          ) {
            obj.parcelle_habitation = {
              section:
                scope.currentReport.properties.parcelleHabitation[0].section,
              numero:
                scope.currentReport.properties.parcelleHabitation[0].numero,
            };
            parccelle = scope.currentReport.properties.parcelleHabitation[0].id;
          }
          const filter = "id_parcelle IN ('" + parccelle + "')";
          QueryFactory.data(scope.demandeUrbaFti.uid, filter)
            .then((res) => {
              if (
                res !== undefined &&
                res.data !== undefined &&
                res.data.features !== undefined &&
                res.data.features[0] !== undefined
              ) {
                obj.demande = res.data.features[0].properties;
              }
            })
            .catch((err) => {
              err.stack;
            });

          translateTableauRadioValues(obj.tableau_produit, [
            'fiche_produit',
            'securite_transmise',
            'toxicite',
          ]);

          translateTableauRadioValues(obj.dechets_produit, ['risque_dechet']);

          setAllChildObjectEmptyValuesToEmptyString(obj);

          def.resolve(obj);
          return def.promise;
        };

        const translateTableauRadioValues = (tableData, properties) => {
          if (tableData && Array.isArray(tableData)) {
            tableData.forEach((row) => {
              properties.forEach((property) => {
                row[property] = getTranslatedBooleanValue(row[property]);
              });
            });
          }
        };

        const getTranslatedBooleanValue = (value) => {
          if (
            value === null ||
            value === undefined ||
            gaJsUtils.isEmptyObject(value)
          ) {
            return '';
          }
          return value === '1'
            ? $filter('translate')('common.yes')
            : $filter('translate')('common.no');
        };

        const setAllChildObjectEmptyValuesToEmptyString = (rapport) => {
          if (rapport) {
            Object.keys(rapport).forEach((property) => {
              if (rapport[property]) {
                if (gaJsUtils.isEmptyObject(rapport[property])) {
                  rapport[property] = '';
                }
                if (
                  rapport[property].constructor === Object ||
                  rapport[property].constructor === Array
                ) {
                  setAllChildObjectEmptyValuesToEmptyString(rapport[property]);
                }
              }
            });
          }
        };

        /**
         * refresh dossiers actions
         * @TODO remove when directive is done
         */
        let refreshDossierActions = () => {
          $rootScope.$broadcast('refreshDossierActions', {
            fid: scope.currentReport.id,
            ftid: scope.dossierFti.uid,
          });
        };

        /**
         * Check wether a report is valid and can be sumbitted
         */

        scope.$on('$typeahead.select', (v, i) => {
          $timeout(function () {
            scope.validReport();
          });
        });
        scope.validReport = () => {
          if (angular.isUndefined(scope.currentReport.properties)) {
            return false;
          }

          let valid = true,
            props = scope.currentReport.properties;

          // mandatory
          if (!props.ref_dossier || props.ref_dossier === '') {
            valid = false;
          }

          return valid;
        };

        let toggleReportBranches = (isnew) => {
          scope.reportTree.forEach((b, idx) => {
            if (idx > 0) {
              if (isnew) {
                b.classes.push('hiddenTreeBranch');
              } else {
                b.classes.splice(b.classes.indexOf('hiddenTreeBranch'));
              }
            }
          });
        };

        /**
         * Whenever the id is set,
         * allow to upload
         */
        scope.$watch('currentReport.id', (id) => {
          if (angular.isDefined(id)) {
            let dossierAttachmentInfo = ancBacTools.getCurrentDossierAttachmentsInfos(
              scope.doss,
              scope.currentReport
            );
            scope.dossierAttachmentData = {
              id: id,
              featuretype: 'kis_bac_dossier',
              attachmentsNo:
                dossierAttachmentInfo !== null
                  ? dossierAttachmentInfo.dossierAttachmentsNo
                  : 0,
            };
            toggleReportBranches(0);
            resetNewControle();
          } else {
            toggleReportBranches(1);
          }
        });

        // pick agent
        scope.$watch(
          'newControleAgentPicker.value',
          (nap) => {
            if (
              nap &&
              angular.isDefined(nap) &&
              angular.isDefined(scope.newControle)
            ) {
              scope.newControle.agent = nap.login;
              scope.newControle.agent_name = nap.name + ' ' + nap.vorname;
              scope.newControleAgentPicker = { value: false };
            }
          },
          1
        );

        /**
         * save report
         */
        scope.saveReport = (tmpReference) => {
          let tempDossier = angular.copy(scope.currentReport);
          let alerte = BacAppFactory.getAlerteColorClass(
            Date.parse(scope.currentReport.properties.alerte_echeance)
          );
          scope.$broadcast('alerteColor', alerte);
          delete tempDossier.properties.attachmentsInfos;
          if (typeof ancAppAndroid == 'undefined')
            dateUtils.convertAllDatesToTimestamps(
              tempDossier.properties,
              dossierDateNames
            );
          const featureCollection = {
            type: 'FeatureCollection',
            features: [
              BacAppFactory.bacDossierToDossier(tempDossier, tmpReference),
            ],
          };

          gaDomUtils.showGlobalLoader();

          if (angular.isUndefined(scope.currentReport.id)) {
            if (scope.currentReport.newFromMap)
              delete scope.currentReport.newFromMap;

            BacAppFactory.adddossier(featureCollection).then(
              (res) => {
                if (res.data === 'already_exist') {
                  require('toastr').error(
                    'Cette référence de dossier est déjà utilisée.',
                    '',
                    {
                      positionClass: 'toast-bottom-left',
                    }
                  );
                  gaDomUtils.hideGlobalLoader();
                } else {
                  require('toastr').success('Dossier enregistré', '', {
                    positionClass: 'toast-bottom-left',
                  });

                  scope.currentReport.id = res.data[0].id;
                  gaDomUtils.hideGlobalLoader();
                  refreshDossierActions();
                  scope.refreshReports();
                  $rootScope.$broadcast(
                    'gcOperationalLayerChange',
                    '',
                    'applyall'
                  );
                }
              },
              () => {
                require('toastr').error(
                  "Impossible d'enregistrer le dossier.",
                  'Erreur',
                  {
                    positionClass: 'toast-bottom-left',
                  }
                );
                gaDomUtils.hideGlobalLoader();
              }
            );
          } else {
            BacAppFactory.updatedossier(featureCollection).then(
              (res) => {
                if (res.data === 'already_exist') {
                  require('toastr').error(
                    'Cette référence de dossier est déjà utilisée.',
                    '',
                    {
                      positionClass: 'toast-bottom-left',
                    }
                  );
                  gaDomUtils.hideGlobalLoader();
                } else {
                  refreshDossierActions();
                  gaDomUtils.hideGlobalLoader();
                  scope.refreshReports();
                  require('toastr').success('Dossier mis à jour.', '', {
                    positionClass: 'toast-bottom-left',
                  });
                }
              },
              (reason) => {
                require('toastr').error(
                  "Impossible d'enregistrer le dossier.",
                  'Erreur',
                  {
                    positionClass: 'toast-bottom-left',
                  }
                );
                gaDomUtils.hideGlobalLoader();
              }
            );
          }
        };
        $rootScope.$on('saveCurrentReport', (event, data) => {
          scope.saveReport();
        });

        /*----------------------------------------------
         * CONTROLE
         *---------------------------------------------*/

        scope.typesControle = BacAppFactory.appCfg.main.controleCfg;

        /**
         * makeNewFiliere
         */
        let resetNewControle = () => {
          scope.newControle = {
            ref_dossier: scope.currentReport.id,
            reference_filiere: '',
            agent: '',
            agent_name: '',
            type: scope.currentReport.properties.prochain_controle
              ? scope.currentReport.properties.prochain_controle
              : scope.typesControle[0].type,
            etat: 'ouvert',
            date_saisie_controle: $filter('date')(
              new Date(),
              'yyyy-MM-ddTHH:mm:ss.sssZ'
            ),
          };
          scope.newControleAgentPicker = { value: false };
          setDefaultControleAgent();
        };

        scope.choixStatutRDV = BacAppFactory.getChoixStatutRDV();

        // used to change the last ctrl type
        scope.newCtrlType = {};

        /**
         * Changer le type d'un controle
         * changeControleType
         */
        scope.changeControleType = (oldCtrlKey) => {
          const ans = confirm(
            "Confirmez-vous le changement du type d'instruction ?\nToute information non commune aux deux types d'instructions sera perdue."
          );
          if (ans) {
            gaDomUtils.showGlobalLoader();
            const oldControle = scope.currentControles.filter((ctrl) => {
              return ctrl.id === oldCtrlKey;
            })[0];

            BacAppFactory.getNewControleData(
              scope.currentReport,
              scope.currentControles,
              scope.newCtrlType.value[oldCtrlKey],
              oldControle
            ).then((newCtrlData) => {
              const dernierControle = angular.copy(
                scope.currentControles.filter(function (ctrl) {
                  return ctrl.id === oldCtrlKey;
                })[0]
              );
              dernierControle.properties.type =
                scope.newCtrlType.value[oldCtrlKey];

              if (dernierControle.properties.ref_demande_autorisation_urbanisme)
                dernierControle.properties.ref_demande_autorisation_urbanisme = null;

              // update controle type
              BacAppFactory.updatecontrole({
                type: 'FeatureCollection',
                features: [dernierControle],
              }).then(
                (res) => {
                  refreshListeControles();
                  if (newCtrlData) {
                    newCtrlData.conformite = {};
                    // update controle detail (json)
                    BacAppFactory.addcontroledetail(
                      newCtrlData,
                      scope.currentReport.id,
                      dernierControle.id
                    ).then(
                      (res) => {
                        scope.currentReport.properties.prochain_controle =
                          scope.newCtrlType.value[oldCtrlKey];
                        gaDomUtils.hideGlobalLoader();
                        scope.saveReport();
                      },
                      () => {
                        gaDomUtils.hideGlobalLoader();
                      }
                    );
                  } else {
                    gaDomUtils.hideGlobalLoader();
                  }
                },
                () => {
                  gaDomUtils.hideGlobalLoader();
                }
              );
            });
          }
        };

        $rootScope.$on('refresh_liste_controle', function (event, data) {
          refreshListeControles();
        });

        /**
         * addControleToDossier
         */
        scope.addControleToDossier = (
          date_passage_rdv,
          open_calendar,
          select_new_branch
        ) => {
          let filiere_id;
          if (angular.isUndefined(scope.newCtrlType.value)) {
            scope.newCtrlType.value = {};
          }
          scope.typeToAdd = angular.copy(scope.newControle.type);

          // recuperation des cles communes avec l'ancien controle
          BacAppFactory.getNewControleData(
            scope.currentReport,
            scope.currentControles,
            scope.newControle.type
          ).then(
            (newCtrlData) => {
              console.log(newCtrlData);
              if (newCtrlData && Object.keys(newCtrlData).length > 0) {
                if (
                  !confirm(
                    "Récupérer les informations disponibles à partir de l'instruction précédente ?"
                  )
                ) {
                  newCtrlData = false;
                }
              }

              let toSubmit = angular.copy(scope.newControle);
              delete toSubmit.agent_name;
              toSubmit.statut_facture = 'aucune';

              // create controle feature collection
              const cFC = {
                type: 'FeatureCollection',
                features: [
                  {
                    type: 'Feature',
                    properties: toSubmit,
                  },
                ],
              };

              if (
                angular.isDefined(
                  scope.currentReport.properties
                    .type_prochain_controle_preconise
                ) &&
                scope.currentReport.properties
                  .type_prochain_controle_preconise != null
              ) {
                if (
                  scope.currentReport.properties
                    .type_prochain_controle_preconise !==
                  cFC.features[0].properties.type
                )
                  scope.currentReport.properties.date_prochain_controle_preconise = null;
              }

              BacAppFactory.addcontrole(
                cFC,
                scope.currentReport.id,
                filiere_id
              ).then(
                (res) => {
                  const newControleId = res.data;

                  if (angular.isDefined(date_passage_rdv)) {
                    if (
                      date_passage_rdv != null &&
                      date_passage_rdv.length > 0
                    ) {
                      if (!newCtrlData) {
                        newCtrlData = {};
                      }

                      if (!newCtrlData.datesDossier) {
                        newCtrlData.datesDossier = {};
                      }

                      newCtrlData.datesDossier.date_controle_rdv = date_passage_rdv;
                    }
                  }
                  // init new ctrl data
                  if (newCtrlData) {
                    BacAppFactory.addcontroledetail(
                      newCtrlData,
                      scope.currentReport.id,
                      newControleId
                    ).then((res) => {
                      scope.newCtrlType.value[newControleId] = scope.typeToAdd;
                      console.log(scope.newControle.type);
                      if (open_calendar) {
                        scope.actionPriseRdv(true);
                      }
                    });
                  }
                  scope.newControleId = newControleId;
                  resetNewControle();
                  require('toastr').success(
                    'Instruction ajoutée au dossier.',
                    '',
                    {
                      positionClass: 'toast-bottom-left',
                    }
                  );

                  // change le statut du dossier
                  scope.currentReport.properties.etat_dossier = 'en_cours';
                  scope.currentReport.properties.prochain_controle =
                    toSubmit.type;
                  scope.saveReport();

                  setDossierArborescence(false, newControleId);
                  gaDomUtils.hideGlobalLoader();
                },
                () => {
                  gaDomUtils.hideGlobalLoader();
                }
              );
            },
            function () {
              gaDomUtils.hideGlobalLoader();
            }
          );
        };

        /**
         * Recuperation de l'url du formulaire de controle
         */
        scope.getFormulaireControleURL = () => {
          let file;
          scope.typesControle.forEach((x) => {
            if (scope.currentControle.properties) {
              if (x.type === scope.currentControle.properties.type)
                file = x.template;
            }
          });

          return 'js/XG/widgets/bacapp/main/views/controle/' + file;
        };

        let setRefDossierAutorisationUrba = () => {
          if (
            scope.currentControle.properties.type === 'DAU' ||
            scope.currentControle.properties.type === 'DUB'
          ) {
            if (angular.isDefined(scope.cdata.demande_autorisation_urbanisme)) {
              if (
                angular.isDefined(scope.cdata.demande_autorisation_urbanisme)
              ) {
                let one, two, three, four, five;
                Object.keys(scope.cdata.demande_autorisation_urbanisme).forEach(
                  (type) => {
                    if (
                      scope.cdata.demande_autorisation_urbanisme[type] == null
                    )
                      scope.cdata.demande_autorisation_urbanisme[type] = '';

                    const toSet =
                      scope.cdata.demande_autorisation_urbanisme[type].length >
                      0
                        ? scope.cdata.demande_autorisation_urbanisme[type]
                        : '';

                    if (type === 'type') one = toSet;

                    if (type === 'insee') two = toSet;

                    if (type === 'annee') three = toSet;

                    if (type === 'code_ref') four = toSet;

                    if (type === 'suffixe') five = toSet;
                  }
                );

                one = angular.isDefined(one) ? one + ' ' : '';
                two = angular.isDefined(two) ? two + ' ' : '';
                three = angular.isDefined(three) ? three + ' ' : '';
                four = angular.isDefined(four) ? four + ' ' : '';
                five = angular.isDefined(five) ? five : '';

                scope.currentControle.properties.ref_demande_autorisation_urbanisme =
                  one + two + three + four + five;
              }
            }
          } else if (
            scope.currentControle.properties.type === 'DAACT' ||
            scope.currentControle.properties.type === 'DC'
          ) {
            if (angular.isDefined(scope.cdata.reference_daact)) {
              scope.currentControle.properties.ref_demande_autorisation_urbanisme =
                scope.cdata.reference_daact;
            }
          } else if (
            scope.currentControle.properties.type === 'RDR' ||
            scope.currentControle.properties.type === 'DB'
          ) {
            if (angular.isDefined(scope.cdata.reference_rdr)) {
              scope.currentControle.properties.ref_demande_autorisation_urbanisme =
                scope.cdata.reference_rdr;
            }
          } else if (scope.currentControle.properties.type === 'EREU') {
            if (angular.isDefined(scope.cdata.reference_ereu)) {
              scope.currentControle.properties.ref_demande_autorisation_urbanisme =
                scope.cdata.reference_ereu;
            }
          } else if (
            scope.currentControle.properties.type === 'DRRAC' ||
            scope.currentControle.properties.type === 'DR'
          ) {
            if (angular.isDefined(scope.cdata.reference_drrac)) {
              scope.currentControle.properties.ref_demande_autorisation_urbanisme =
                scope.cdata.reference_drrac;
            }
          }
        };

        let getLogin = (username) => {
          let res;
          if (userslist && userslist.length) {
            userslist.forEach((user) => {
              const compare = user.vorname + ' ' + user.name;
              if (compare === username) {
                res = user.login;
              }
            });
          }
          return res;
        };

        function getDatePassageName(type) {
          let dateToInsert;
          switch (type) {
            case 'DRRAC':
            case 'DR':
              dateToInsert = 'date_demande';
              break;
            case 'RDR':
            case 'DUB':
            case 'DB':
            case 'CSDI':
              dateToInsert = 'date_reception';
              break;
            case 'DAACT':
              dateToInsert = 'date_fixee_daact';
              break;
            case 'DAU':
              dateToInsert = 'date_decision';
              break;
            default:
              dateToInsert = 'date_controle';
              break;
          }
          return dateToInsert;
        }

        /**
         * saveControleDetail
         */
        scope.saveControleDetail = (majControle) => {
          if (
            !gaJsUtils.checkNestedProperty('general.statut_rdv', scope.cdata)
          ) {
            gaJsUtils.setNestedProperty(
              'general.statut_rdv',
              scope.cdata,
              null
            );
          }

          if (angular.isUndefined(scope.cdata.conformite)) {
            scope.cdata.conformite = {
              agent: null,
              avis_agent: null,
              avis: null,
              responsable: null,
            };
          }

          // Set idDossier to get img of map in report edition
          scope.cdata.idDossier = scope.currentReport.id;

          if (angular.isDefined(scope.cdata.datesDossier)) {
            Object.keys(scope.cdata.datesDossier).forEach((date) => {
              if (scope.cdata.datesDossier[date] === false) {
                scope.cdata.datesDossier[date] = null;
              }
            });
          } else {
            scope.cdata.datesDossier = {};
          }

          //insertion de la date à insérer dans date_passage selon le type d'instruction
          const dateToInsert = getDatePassageName(
            scope.currentControle.properties.type
          );

          if (angular.isDefined(scope.cdata.datesDossier)) {
            if (
              angular.isDefined(scope.cdata.datesDossier[dateToInsert]) &&
              scope.cdata.datesDossier[dateToInsert] != null &&
              scope.cdata.datesDossier[dateToInsert] instanceof Date &&
              !isNaN(scope.cdata.datesDossier[dateToInsert].valueOf())
            ) {
              if (
                Object.keys(scope.cdata.datesDossier[dateToInsert]).length ===
                  0 &&
                !(
                  scope.cdata.datesDossier[dateToInsert] instanceof Date &&
                  !isNaN(scope.cdata.datesDossier[dateToInsert].valueOf())
                )
              )
                scope.cdata.datesDossier[dateToInsert] = null;
            }
          }

          const toCompare = {
            agent: getLogin(scope.cdata.conformite.agent),
            avis: scope.cdata.conformite.valeur,
            avis_agent: scope.cdata.conformite.valeur_agent,
            date_avis: scope.cdata.datesDossier.date_avis,
            date_avis_agent: scope.cdata.datesDossier.date_avis_controleur,
            date_passage:
              scope.currentControle.properties.type == 'DAU' &&
              angular.isDefined(scope.cdata.ddc) &&
              angular.isDefined(scope.cdata.ddc[dateToInsert])
                ? $filter('date')(
                    scope.cdata.ddc[dateToInsert],
                    'yyyy-MM-ddTHH:mm:ss.sssZ'
                  )
                : $filter('date')(
                    scope.cdata.datesDossier[dateToInsert],
                    'yyyy-MM-ddTHH:mm:ss.sssZ'
                  ),
            id_demandeur: scope.currentControle.properties.id_demandeur,
            responsable: getLogin(scope.cdata.conformite.responsable),
            statut_rdv: scope.cdata.general.statut_rdv,
          };

          console.log(toCompare);

          scope.currentControle.properties.date_passage = $filter('date')(
            scope.cdata.datesDossier[dateToInsert],
            'yyyy-MM-ddTHH:mm:ss.sssZ'
          );
          Object.keys(scope.currentControle.properties).forEach((currProp) => {
            Object.keys(toCompare).forEach((newProp) => {
              if (currProp === newProp) {
                if (
                  scope.currentControle.properties[currProp] !==
                  toCompare[newProp]
                ) {
                  scope.currentControle.properties[currProp] =
                    toCompare[newProp];
                }
              }
            });
          });

          // Format dates Avis
          if (scope.currentControle.properties.date_avis) {
            scope.currentControle.properties.date_avis = $filter('date')(
              new Date(scope.currentControle.properties.date_avis),
              'yyyy-MM-ddTHH:mm:ss.sssZ'
            );
            scope.cdata.datesDossier.date_avis =
              scope.currentControle.properties.date_avis;
          }
          if (scope.currentControle.properties.date_avis_agent) {
            scope.currentControle.properties.date_avis_agent = $filter('date')(
              new Date(scope.currentControle.properties.date_avis_agent),
              'yyyy-MM-ddTHH:mm:ss.sssZ'
            );
            scope.cdata.datesDossier.date_avis_controleur =
              scope.currentControle.properties.date_avis_agent;
          }

          let needToSaveReport = false;
          if (
            angular.isDefined(scope.currentControle.properties.etat) &&
            scope.currentControle.properties.etat === 'clos' &&
            scope.currentControle.properties.est_dernier_controle_cloture ===
              true
          ) {
            if (scope.currentControle.properties.date_avis) {
              scope.currentReport.properties.date_dernier_controle = $filter(
                'date'
              )(
                new Date(scope.currentControle.properties.date_avis),
                'yyyy-MM-ddTHH:mm:ss.sssZ'
              );
            }

            // maj avis dernier controle
            if (
              angular.isDefined(scope.cdata.conformite.valeur) &&
              scope.currentReport.properties.avis_dernier_controle !==
                scope.cdata.conformite.valeur
            ) {
              scope.currentReport.properties.avis_dernier_controle =
                scope.cdata.conformite.valeur;
              needToSaveReport = true;
            }
          }
          if (needToSaveReport) {
            scope.saveReport();
          }

          setRefDossierAutorisationUrba();

          /**
           * Si controle cloturer sans date de passage  : date  passage = date avis
           */
          if (
            (!scope.currentControle.properties.date_passage ||
              !scope.currentControle.properties.date_passage.length) &&
            angular.isDefined(scope.currentControle.properties.date_avis)
          ) {
            scope.currentControle.properties.date_passage =
              scope.currentControle.properties.date_avis;
          }

          let ctrlLabel;
          if (
            scope.currentControle.properties.type === 'DUB' ||
            scope.currentControle.properties.type === 'DAU'
          ) {
            ctrlLabel = BacAppFactory.getControleName(
              scope.currentControle.properties.type,
              scope.currentControle.properties
                .ref_demande_autorisation_urbanisme
            );
          } else {
            ctrlLabel = BacAppFactory.getControleName(
              scope.currentControle.properties.type,
              scope.currentControle.properties.date_passage
            );
          }
          scope.currentBranch.label = ctrlLabel;

          const def = $q.defer();
          majControle = majControle || 0;
          gaDomUtils.showGlobalLoader();


          BacAppFactory.updatecontrole({
            type: 'FeatureCollection',
            features: [scope.currentControle],
          }).then(
            () => {
              scope.checkDiffCdata = angular.copy(scope.cdata);

              // add controle detail
              BacAppFactory.addcontroledetail(
                scope.cdata,
                scope.currentReport.id,
                scope.currentControle.id
              ).then(
                (res) => {
                  require('toastr').success(
                    "Informations de l'instruction enregistrées.",
                    '',
                    {
                      positionClass: 'toast-bottom-left',
                    }
                  );
                  // reset dirty variable
                  scope.ctrlFormIsDirty = false;
                  gaDomUtils.hideGlobalLoader();

                  // refresh liste dossiers
                  scope.refreshReports();

                  def.resolve();
                },
                () => {
                  require('toastr').error(
                    "Un problème est survenu lors de l'enregistitrement de l'instruction.",
                    'Erreur',
                    {
                      positionClass: 'toast-bottom-left',
                    }
                  );
                }
              );
            },
            () => {
              require('toastr').error(
                "Un problème est survenu lors de l'enregistrement de l'instruction.",
                'Erreur',
                {
                  positionClass: 'toast-bottom-left',
                }
              );
            }
          );
          return def.promise;
        };

        /**
         * Return le label d'un controle d'apres son type
         * (pour utilisation dans les vues)
         * @param type
         * @returns {*}
         */
        scope.getControleName = (type) => {
          return BacAppFactory.getControleName(type);
        };

        function calcDelai(wcfg) {
          let delai = 0;
          if (wcfg.delai) {
            if (wcfg.delai.type === 'jour') {
              delai = wcfg.delai.value;
            } else if (wcfg.delai.type === 'semaine') {
              delai = wcfg.delai.value * 7;
            } else if (wcfg.delai.type === 'mois') {
              delai = wcfg.delai.value * 30;
            } else if (wcfg.delai.type === 'année') {
              delai = wcfg.delai.value * 365;
            }
          }
          return delai;
        }

        scope.openedInstructions = (instructions) => {
          if (instructions) {
            return ancBacTools.openedControles(instructions);
          }
        };

        let avisControleDialog;
        scope.pre_appliquerAvisControle = (absentOuRefus) => {
          let origine_du_rapport_annulation = null;
          let listeDeroulantes = FeatureTypeFactory.getFeatureByUid(
            'kis_bac_listes_deroulantes_controles'
          );
          if (listeDeroulantes) {
            let keyvals = getDomaineRestriction(listeDeroulantes);
            if (
              keyvals !== undefined &&
              keyvals.origine_du_report_annulation !== undefined
            ) {
              origine_du_rapport_annulation =
                keyvals.origine_du_report_annulation[
                  scope.cdata.general.origine_du_report_annulation
                ];
            }
          }

          /**
           * A savoir : le remplissage du statut doit faire apparaitre 2 champs : Origine : / Commentaires
           */
          scope.currentControle.properties.origine_du_report_annulation_rdv = origine_du_rapport_annulation
            ? origine_du_rapport_annulation
            : null;
          scope.currentControle.properties.commentaire_rdv =
            scope.cdata.general && scope.cdata.general.statut_rdv_commnentaire
              ? scope.cdata.general.statut_rdv_commnentaire
              : null;
          scope.currentControle.properties.statut_rdv =
            scope.cdata.general && scope.cdata.general.statut_rdv
              ? scope.cdata.general.statut_rdv
              : null;

          scope.saveControleDetail();

          if (absentOuRefus) {
            if (confirm("Veuillez-vous fermer l'instruction ?")) {
              /**
               * Lors de la fermeture du controle suite à remplissage du statut rdv,
               * la date du jour doit etre renseignée au niveau de la date du responsable
               */
              if (!scope.cdata.datesDossier.date_avis) {
                scope.cdata.datesDossier.date_avis = $filter('date')(
                  new Date(),
                  'yyyy-MM-ddTHH:mm:ss.sssZ'
                );
              }
              scope.appliquerAvisControle(1);
              scope.cdata.general.statut_rdv_commnentaire = null;
              scope.cdata.general.origine_du_report_annulation = null;
            }
          } else {
            scope.cdata.general.statut_rdv_commnentaire = null;
            scope.cdata.general.origine_du_report_annulation = null;
            scope.nextControle = {};

            const workflowcfg = angular.copy(
              BacAppFactory.appCfg.main.controleWorkflowCfg
            );

            if (Object.keys(workflowcfg).length === 0) {
              require('toastr').error(
                "La configuration des enchaînements de l'instruction n'est pas faite.",
                'Erreur',
                {
                  positionClass: 'toast-bottom-left',
                }
              );
              return;
            }
            scope.possibilitesProchainCtrl = [] ;
            scope.checkLabel = scope.cdata.conformite.valeur;
            workflowcfg.forEach((wcfg) => {
              // seulement si meme type et meme avis
              if (!scope.cdata.general) scope.cdata.general = {};
              let check = [];
              if (scope.avisCtrl && wcfg.avis) {
                check = scope.avisCtrl.filter(
                  (ligneAvis) =>
                    ligneAvis.key == wcfg.avis &&
                    ligneAvis.type_controle == wcfg.current_controle
                );
              }
              if (!check[0]) {
                check[0] = scope.avisCtrl[wcfg.avis];
              }
              if (check !== undefined && check[0] !== undefined) {
                var checkLabel = check[0].label;
              }

              if (checkLabel &&
                scope.cdata.conformite.valeur === checkLabel &&
                scope.currentControle.properties.type === wcfg.current_controle
              ) {
                let delai = 0;
                if (wcfg.avec_delai && wcfg.delai) {
                  if (wcfg.delai.type === 'jour') {
                    delai = wcfg.delai.value;
                  } else if (wcfg.delai.type === 'semaine') {
                    delai = wcfg.delai.value * 7;
                  } else if (wcfg.delai.type === 'mois') {
                    delai = wcfg.delai.value * 30;
                  } else if (wcfg.delai.type === 'année') {
                    delai = wcfg.delai.value * 365;
                  }
                  wcfg.delai.typePluriel =
                    wcfg.delai.value > 1 && wcfg.delai.type !== 'mois'
                      ? wcfg.delai.type + 's'
                      : wcfg.delai.type;
                }
                const dateToInsert = getDatePassageName(
                  scope.currentControle.properties.type
                );
                const date_passage = scope.cdata.datesDossier[dateToInsert];
                scope.possibilitesProchainCtrl.push({
                  avec_delai: wcfg.avec_delai,
                  label: BacAppFactory.getControleName(wcfg.next_controle),
                  type: wcfg.next_controle,
                  delai: angular.copy(wcfg.delai),
                  date: $filter('date')(
                    moment().add(delai, 'day').toDate(),
                    'yyyy-MM-ddTHH:mm:ss.sssZ'
                  ),
                  dateMax: calcDateMax(
                    date_passage,
                    scope.cdata.datesDossier.date_avis,
                    delai
                  ),
                });

                // si un seul on l'ouvre directement
                if (scope.possibilitesProchainCtrl.length === 1) {
                  scope.nextControle.data = scope.possibilitesProchainCtrl[0];
                }
              }
            });
            if (1) {
              // dialog
              avisControleDialog = ngDialog.open({
                template:
                  'js/XG/widgets/bacapp/main/views/modals/modal.avis.controle.html',
                className:
                  'ngdialog-theme-plain width800 nopadding miniclose error_dialog',
                closeByDocument: false,
                scope: scope,
              });
            }
          }
        };

        function calcDateMax(date_passage, date_avis, delai) {
          const date_base_string = date_passage != null && date_passage.length > 0
            ? date_passage
            : date_avis;
          let dateMax = new Date(Date.parse(date_base_string));
          dateMax.setDate(dateMax.getDate() + delai);
          return dateMax;
        }

        /**
         * checkDateProchainControle
         * @returns {boolean}
         */
        scope.checkDateProchainControle = () => {
          let valid = false;

          if (scope.nextControle.data) {
            const d1 = new Date(scope.nextControle.data.date);
            const d2 = new Date(scope.nextControle.data.dateMax);

            if (d1 <= d2) {
              valid = true;
            }
          }

          return valid;
        };

        let calendarEventTypes = [];
        let getEventTypes = () => {
          // AddMobile
          if (!scope.mobile) {
            CalendarFactory.geteventtypes().then(
              (res) => {
                calendarEventTypes = CalendarFactory.resources.event_types;
              },
              () => {}
            );
          }
        };
        getEventTypes();

        /**
         * Application finale de l'avis apres choix du prochain controle
         */
        scope.appliquerAvisControle = (appliqueDepuisStatutCtrl) => {
          if (1) {
            gaDomUtils.showGlobalLoader();
            // save controle detail
            scope.saveControleDetail().then(
              () => {
                scope.currentControle.properties.etat = 'clos';
                scope.currentControle.properties.est_dernier_controle_cloture = true;
                scope.currentControle.properties.avis = !appliqueDepuisStatutCtrl
                  ? scope.cdata.conformite.valeur
                  : scope.cdata.general.statut_rdv;

                scope.currentControle.properties.date_avis = $filter('date')(
                  scope.cdata.datesDossier.date_avis,
                  'yyyy-MM-ddTHH:mm:ss.sssZ'
                );
                scope.currentControle.properties.date_avis_agent = $filter(
                  'date'
                )(
                  scope.cdata.datesDossier.date_avis_controleur,
                  'yyyy-MM-ddTHH:mm:ss.sssZ'
                );

                scope.currentControle.properties.statut_rdv = scope.cdata
                  .general.statut_rdv
                  ? scope.cdata.general.statut_rdv
                  : 'present';

                  if (
                    !appliqueDepuisStatutCtrl &&
                    scope.possibilitesProchainCtrl.length
                  ) {
                    scope.currentControle.properties.date_prochain_controle_preconise =
                      scope.nextControle.data.dateMax &&
                      scope.nextControle.data.delai
                        ? $filter('date')(
                            scope.nextControle.data.dateMax,
                            'yyyy-MM-ddTHH:mm:ss.sssZ'
                          )
                        : null;
                    scope.currentControle.properties.type_prochain_controle_preconise = angular.isDefined(
                      scope.nextControle.data.type
                    )
                      ? scope.nextControle.data.type
                      : null;
                  }



                // update controle object
                BacAppFactory.updatecontrole({
                  type: 'FeatureCollection',
                  features: [scope.currentControle],
                }).then(
                  (res) => {
                    let listeControlesClos = scope.currentControles;

                    for (let i = listeControlesClos.length - 1; i >= 0; i--) {
                      if (
                        listeControlesClos[i].id === scope.currentControle.id
                      ) {
                        console.log(listeControlesClos);
                        listeControlesClos.splice(i, 1);
                      }
                    }

                    for (let i = listeControlesClos.length - 1; i >= 0; i--) {
                      listeControlesClos[
                        i
                      ].properties.est_dernier_controle_cloture = false;
                      BacAppFactory.updatecontrole(
                        {
                          type: 'FeatureCollection',
                          features: [listeControlesClos[i]],
                        },
                        () => {
                          gaDomUtils.hideGlobalLoader();
                        }
                      );
                    }

                    // update dossier
                    scope.currentReport.properties.type_dernier_controle =
                      scope.currentControle.properties.type;
                    scope.currentReport.properties.avis_dernier_controle =
                      scope.currentControle.properties.avis;
                    if (scope.currentControle.properties.date_passage) {
                      scope.currentReport.properties.date_dernier_controle = $filter(
                        'date'
                      )(
                        new Date(scope.currentControle.properties.date_passage),
                        'yyyy-MM-ddTHH:mm:ss.sssZ'
                      );
                    } else if (scope.currentControle.properties.date_avis) {
                      scope.currentReport.properties.date_dernier_controle = $filter(
                        'date'
                      )(
                        new Date(scope.currentControle.properties.date_avis),
                        'yyyy-MM-ddTHH:mm:ss.sssZ'
                      );
                    }

                    scope.currentReport.properties.prochain_controle = '';
                    scope.currentReport.properties.date_prochain_controle = null;

                    if (!appliqueDepuisStatutCtrl) {
                      // sauf si pas de workflow
                      if (
                        !appliqueDepuisStatutCtrl &&
                        scope.possibilitesProchainCtrl.length
                      ) {
                        scope.currentReport.properties.prochain_controle =
                          scope.nextControle.data.type;
                        scope.currentReport.properties.date_prochain_controle = scope
                          .nextControle.data.delai
                          ? scope.nextControle.data.date
                          : null;
                      }

                      scope.saveReport();

                      // add event (sauf si sans délai)
                      if (
                        $rootScope.xgos &&
                        $rootScope.xgos.portal &&
                        $rootScope.xgos.portal.parameters &&
                        $rootScope.xgos.portal.parameters.calendar &&
                        $rootScope.xgos.portal.parameters.calendar.active &&
                        scope.nextControle.data &&
                        scope.nextControle.data.delai
                      ) {
                        const dossier = angular.copy(
                          scope.currentReport.properties
                        );

                        let adresseComplete = 'Adresse: ';
                        if (dossier.adresse_num_rue)
                          adresseComplete += dossier.adresse_num_rue + ' ';
                        if (dossier.adresse_rue)
                          adresseComplete += dossier.adresse_rue + ' ';
                        if (dossier.adresse_cp)
                          adresseComplete += dossier.adresse_cp + ' ';
                        if (dossier.adresse_ville)
                          adresseComplete += dossier.adresse_ville;

                        let description = '';
                        if (dossier.proprietaires.length) {
                          if (dossier.proprietaires.length === 1) {
                            description = 'Propriétaire: ';
                          } else {
                            description = 'Propriétaires: ';
                          }
                          for (
                            let i = 0;
                            i < dossier.proprietaires.length;
                            i++
                          ) {
                            if (dossier.proprietaires[i].civilite) {
                              if (
                                dossier.proprietaires[i].civilite === 'Monsieur'
                              ) {
                                description += 'M. ';
                              } else if (
                                dossier.proprietaires[i].civilite === 'Madame'
                              ) {
                                description += 'Mme ';
                              }
                            }
                            if (dossier.proprietaires[i].nom)
                              description += dossier.proprietaires[i].nom + ' ';
                            if (dossier.proprietaires[i].prenom)
                              description += dossier.proprietaires[i].prenom;
                            if (
                              dossier.proprietaires.length !== 1 &&
                              i !== dossier.proprietaires.length - 1
                            )
                              description += ', ';
                          }
                        }
                        if (dossier.locataires.length) {
                          description += '\n\nOccupant: ';
                          if (dossier.locataires[0].civilite) {
                            if (dossier.locataires[0].civilite === 'Monsieur') {
                              description += 'M. ';
                            } else if (
                              dossier.locataires[0].civilite === 'Madame'
                            ) {
                              description += 'Mme ';
                            }
                          }
                          if (dossier.locataires[0].nom)
                            description += dossier.locataires[0].nom + ' ';
                          if (dossier.locataires[0].prenom)
                            description += dossier.locataires[0].prenom;
                        }
                        if (description !== '') {
                          description = description + '\n\n' + adresseComplete;
                        } else {
                          description = adresseComplete;
                        }
                        let color = 'e74c3c';
                        let type_evenement = 0;
                        calendarEventTypes.forEach((eventType) => {
                          // un seul type de ctrl pr le moment
                          if (1) {
                            if (
                              eventType.properties.type ===
                              'kis_bac_controle_branchement'
                            ) {
                              color = eventType.properties.default_color;
                              type_evenement = eventType.properties.type_id;
                            }
                          }
                        });
                        const controleName = BacAppFactory.getControleName(
                          scope.currentControle.properties.type
                        );
                        const newEvent = {
                          collection: {
                            type: 'FeatureCollection',
                            features: [
                              {
                                type: 'Feature',
                                properties: {
                                  color: color,
                                  title: controleName,
                                  type_evenement: type_evenement,
                                  start: scope.nextControle.data.date,
                                  end: $filter('date')(
                                    moment(scope.nextControle.data.date)
                                      .add(2, 'hour')
                                      .toDate(),
                                    'yyyy-MM-ddTHH:mm:ss.sssZ'
                                  ),
                                  description: description,
                                  place:
                                    scope.currentReport.properties
                                      .adresse_ville,
                                },
                              },
                            ],
                          },
                          linked_objects: [
                            {
                              type: 'FeatureCollection',
                              features: [
                                {
                                  type: 'Feature',
                                  properties: {
                                    feature_id: scope.currentControle.id,
                                    feature_uid: controleFti.uid,
                                  },
                                },
                                {
                                  type: 'Feature',
                                  properties: {
                                    feature_id: scope.currentReport.id,
                                    feature_uid: scope.dossierFti.uid,
                                  },
                                },
                              ],
                            },
                          ],
                          users: [
                            [
                              {
                                login: scope.currentControle.properties.agent,
                                type: 'concerne',
                              },
                            ],
                          ],
                        };

                        CalendarFactory.addevent(newEvent).then(
                          (res) => {
                            const eventid = res.data[0].id;

                            require('toastr').success(
                              "Évenement enregistré dans le calendrier de l'agent.",
                              '',
                              {
                                positionClass: 'toast-bottom-left',
                              }
                            );
                          },
                          () => {
                            require('toastr').error(
                              "Erreur lors de l'ajout de l'événement.",
                              '',
                              {
                                positionClass: 'toast-bottom-left',
                              }
                            );
                          }
                        );
                      }
                    }

                    scope.saveReport();
                    if (
                      angular.isDefined(avisControleDialog) &&
                      !scope.priseRDV.active
                    ) {
                      avisControleDialog.close();
                    }

                    scope.currentBranch.classes.push('inactiveTreeBranch');

                    // undirty
                    scope.ctrlFormIsDirty = 0;

                    scope.reportTree.forEach((b, i) => {
                      if (b.label === 'Instructions') {
                        scope.reportTreeControl.select_branch(b);
                        scope.reportTreeControl.collapse_branch(
                          scope.currentBranch
                        );
                      }
                    });
                    refreshListeControles();
                    gaDomUtils.hideGlobalLoader();
                  },
                  () => {
                    gaDomUtils.hideGlobalLoader();
                    require('toastr').error(
                      'Erreur lors de la mise à jour du instruction.'
                    );
                  }
                );
              },
              () => {
                gaDomUtils.hideGlobalLoader();
                require('toastr').error('Erreur zeuiobeg');
              }
            );
          }
        };

        //resetDossierArborescence
        $rootScope.$on('resetDossierArborescence', (event, data) => {
          setDossierArborescence();
        });

        let presetDereg = $rootScope.$on(
          'preset_bac_dossier',
          (event, data) => {
            if (data.adresse && !data.newFromMap) {
              scope.editReport(
                false,
                data.feature.geometry,
                undefined,
                data.adresse
              );
            } else if (data.adresse && data.newFromMap) {
              scope.editReport(
                false,
                data.feature.geometry,
                undefined,
                data.adresse,
                undefined,
                undefined,
                true
              );
            } else {
              scope.editReport(false, data.feature.geometry);
            }
          }
        );

        // sans ca est appele plusieurs fois si le widget mapwidget est toggled plusieurs fois
        scope.$on('$destroy', () => {
          presetDereg();
        });

        /**
         * edit report
         */
        scope.$watch('$routeUpdate', () => {
          const fid = $location.search().fid;
          if (fid) {
            if (fid.split('.')[0] === 'kis_bac_dossier') {
              $rootScope.$broadcast('bac_open_dossier', [{ id: fid }]);
            } else if (fid.split('.')[0] === 'kis_bac_dossier_controle') {
              BacAppFactory.getdossierbycontroleid(fid).then((res) => {
                if (res.data.features[0]) {
                  $rootScope.$broadcast('bac_open_controle', [
                    {
                      dossier_id: res.data.features[0].id,
                      controle_id: fid,
                    },
                  ]);
                }
              });
            }
          }
        });

        scope.buttonEditIcon = [
          {
            label: 'Bouton',
            type: 'component',
            description: '',
            config: {
              name: 'button',
              click: ['crud_update'],
            },
            cfg: {
              icon: {
                name: 'pencil-square-o',
                spinning: false,
              },
              iconOrLabel: 'icon',
              size: 'btn-xs',
              style: 'btn-default cursorHelp',
              label: 'Button',
              title: 'Editer le dossier',
            },
          },
        ];

        scope.tooltipTitle = {};
        scope.tooltipTitle.titleFilter = 'Appliquer un filtre';
        scope.tooltipTitle.class = 'cursorHelp';

        /*
                 DOCUMENT DOSSIER
                 */

        /**
         * setLastImageFiliere
         * @returns {*}
         */
        let setLastImageCarto = function () {
          let def = $q.defer();

          if (angular.isDefined(scope.currentReport.id)) {
            // documents associés à la filiere
            FeatureAttachmentFactory.list(
              'kis_bac_dossier',
              scope.currentReport.id
            ).then(function (res) {
              let documentsCarto = res.data;
              if (documentsCarto.length) {
                // tous les fichiers contenant representation_filiere_x.png
                // classes par l'index x
                const files = [];
                documentsCarto.map((d) => {
                  if (d.indexOf('representation_cartographique') === 0) {
                    const tmp = d.split('_'),
                      idx = angular.isDefined(tmp[2])
                        ? tmp[2].replace('.png', '')
                        : 0;
                    files[idx] = d;
                  }
                });

                // got it
                if (files.length) {
                  def.resolve({
                    id: scope.currentReport.id,
                    file: files[files.length - 1],
                  });
                  // nope
                } else {
                  def.resolve(false);
                }
              } else {
                def.resolve(false);
              }
            });
          } else {
            def.resolve(false);
          }

          return def.promise;

          // recup last filiere img
        };

        scope.dossierCfg = BacAppFactory.appCfg.main.dossierCfg;
        if (typeof AppAndroid == 'undefined') {
          ConfigFactory.checkTemplates(scope.dossierCfg.templates).then(
            (res) => {
              scope.dossierCfg.templates = res.data;
            }
          );
        }

        /**
         * getDocxControle
         * Récupération du document tyoe
         */
        scope.getDocxControle = (fichier, pdf) => {
          if (!fichier) {
            require('toastr').error(
              "Le template word n'a pas été spécifié pour ce type de document",
              '',
              {
                positionClass: 'toast-bottom-left',
              }
            );
            return;
          }
          gaDomUtils.showGlobalLoader();

          const detail =
            'Téléchargement du fichier ' +
            fichier +
            ' par ' +
            $rootScope.xgos.user.login;
          transformDataForDocxGeneration(scope.cdata).then((docxdata) => {
            docxdata.date_current = $filter('date')(new Date(), 'dd/MM/yyyy');
            docxdata._type_controle = scope.typeControle;

            const ctrlLabel = BacAppFactory.getControleName(
              scope.currentControle.properties.type,
              scope.currentControle.properties.date_saisie_controle
            );

            setLastImageCarto().then((lastImageCarto) => {
              if (lastImageCarto) docxdata.image_dossier = lastImageCarto;
              let jsonData = JSON.stringify(docxdata);
              DocumentFactory.generatedocx(
                jsonData,
                fichier,
                scope.currentControle.id,
                pdf
              ).then(
                (doto) => {
                  if (scope.dossierInfosSup !== undefined) {
                    scope.dossierInfosSup.map((extra_field) => {
                      extra_field.restrictions.map((item) => {
                        if (item.listofValues !== undefined) {
                          for (let key in item.listofValues) {
                            if (item.listofValues.hasOwnProperty(key)) {
                              if (
                                item.listofValues[key] ===
                                scope.currentReport.properties[extra_field.name]
                              ) {
                                scope.currentReport.properties[
                                  extra_field.name
                                ] = key;
                              }
                            }
                          }
                        }
                      });
                    });
                  }

                  FeatureHistoryFactory.addaction(
                    scope.dossierFti.uid,
                    scope.currentReport.id,
                    'Edition de rapport',
                    'Edition du rapport (' +
                      ctrlLabel +
                      ') ' +
                      fichier +
                      ' par ' +
                      $rootScope.xgos.user.login
                  );
                  gaDomUtils.hideGlobalLoader();
                  window.open(
                    '/services/' +
                      doto.data.portalid +
                      '/documents/downloaddocx?' +
                      '&name=' +
                      doto.data.name.replace('\\', '/')
                  );
                  // refresh featureattachement
                  $rootScope.$broadcast('refreshFeatureAttachment', {
                    id: scope.currentControle.id,
                    featuretype: 'kis_bac_dossier_controle',
                  });
                },
                () => {
                  gaDomUtils.hideGlobalLoader();
                  require('toastr').error(
                    'Erreur lors de la génération du document.'
                  );
                }
              );
            });
          });
        };

        /**
         * getDocxDossier
         * @param fichier
         */
        scope.getDocxDossier = (fichier, pdf) => {
          gaDomUtils.showGlobalLoader();
          const detail =
            'Téléchargement du fichier ' +
            fichier +
            ' par ' +
            $rootScope.xgos.user.login;

          const promise = BacAppFactory.getZipDocumentsTypes(
            [scope.currentReport.id],
            [fichier],
            pdf
          );
          promise.then(
            (res) => {
              window.open(
                '/services/' +
                  res.data.portalid +
                  '/documents/downloaddocx?' +
                  '&name=' +
                  res.data.name.replace('\\', '/')
              );
              gaDomUtils.hideGlobalLoader();
              // refresh featureattachement
              $rootScope.$broadcast('refreshFeatureAttachment', {
                id: scope.currentReport.id,
                featuretype: 'kis_bac_dossier',
              });
            },
            () => {
              require('toastr').error('Erreur lors de génération du document.');
              gaDomUtils.hideGlobalLoader();
            }
          );
        };
        //supprimer controle du dossier
        scope.removeControleFromDossier = (controle) => {
          const ans = confirm(
            'Êtes-vous certain de vouloir supprimer cette instruction ?'
          );
          if (ans) {
            if (scope.currentControles.length === 1) {
              delete scope.currentReport.properties.type_dernier_controle;
              delete scope.currentReport.properties.avis_dernier_controle;
              delete scope.currentReport.properties.prochain_controle;
              scope.currentReport.properties.date_dernier_controle = null;
              scope.currentReport.properties.date_prochain_controle = null;
            } else {
              for (let i = 0; i < scope.currentControles.length; i++) {
                if (scope.currentControles[i].id === controle.id) {
                  scope.currentControles.splice(i, 1);
                }
              }
              scope.currentReport.properties.type_dernier_controle =
                scope.currentControles[0].properties.type;
              scope.currentReport.properties.avis_dernier_controle =
                scope.currentControles[0].properties.avis;
              const lastControleWithDateAvis = scope.currentControles.find(
                (ctrl) => ctrl.properties.date_avis
              );
              if (lastControleWithDateAvis) {
                scope.currentReport.properties.date_dernier_controle = $filter(
                  'date'
                )(
                  new Date(lastControleWithDateAvis.properties.date_avis),
                  'yyyy-MM-ddTHH:mm:ss.sssZ'
                );
              } else {
                scope.currentReport.properties.date_dernier_controle = null;
              }

              const checkHighestId = [];
              for (let i = scope.currentControles.length - 1; i >= 0; i--) {
                if (scope.currentControles[i].properties.etat === 'clos')
                  checkHighestId.push(
                    scope.currentControles[i].id.replace(
                      /kis_bac_dossier_controle./g,
                      ''
                    )
                  );
              }

              for (let i = scope.currentControles.length - 1; i >= 0; i--) {
                if (
                  scope.currentControles[i].id ===
                  'kis_bac_dossier_controle.' +
                    Math.max.apply(Math, checkHighestId)
                )
                  scope.currentControles[
                    i
                  ].properties.est_dernier_controle_cloture = true;
                BacAppFactory.updatecontrole(
                  {
                    type: 'FeatureCollection',
                    features: [scope.currentControles[i]],
                  },
                  () => {
                    gaDomUtils.hideGlobalLoader();
                  }
                );
              }
            }
            gaDomUtils.showGlobalLoader();
            const promise = BacAppFactory.removecontrole(
              controle.properties.ref_dossier,
              controle.id,
              controle.properties.type
            );
            promise.then(
              (res) => {
                scope.saveReport();
                setDossierArborescence();
                gaDomUtils.hideGlobalLoader();
              },
              () => {
                gaDomUtils.hideGlobalLoader();
              }
            );
          }
        };

        //changer etat du controle
        scope.changeEtat = (controle) => {
          const ans = confirm(
            'Êtes-vous certain de vouloir ré-ouvrir cette instruction ?'
          );
          if (ans) {
            controle.properties.etat = 'ouvert';
            gaDomUtils.showGlobalLoader();
            const promise = BacAppFactory.updatecontrole({
              type: 'FeatureCollection',
              features: [controle],
            });
            promise.then(
              (res) => {
                setDossierArborescence();
                //   scope.getEtatControle();
                gaDomUtils.hideGlobalLoader();
              },
              () => {
                gaDomUtils.hideGlobalLoader();
              }
            );
          }
        };

        //recuperer la premiere controle qui a un etat clos
        scope.getEtatControle = (controle, index) => {
          if (controle.properties.etat === 'ouvert') {
            return false;
          } else if (controle.properties.etat === 'clos') {
            if (index === 0) {
              return true;
            }
          }
          return false;
        };

        //Samedi et Dimanche retourner le Vendredi
        //minutes 0-29 --->0     30-59 --->30
        scope.$watch('nextControle.data.date', (tab) => {
          if (!scope.nextControle) {
            return false;
          }
          if (!scope.nextControle.data || !scope.nextControle.data.date) {
            return false;
          }
          const date_passage_name = getDatePassageName(
            scope.nextControle.data.type
          );
          const date_passage = scope.cdata.datesDossier[date_passage_name];
          // check if date_passage is filled (i.e isUndefined || empty object)
          let isDatePassage = true;
          if (
            angular.isUndefined(date_passage) ||
            (angular.isDefined(date_passage) &&
              date_passage.constructor === Object &&
              Object.entries(date_passage).length === 0)
          ) {
            isDatePassage = false;
          }
          // retrieve delai in days
          let delai;
          if (scope.nextControle.data && scope.nextControle.data.delai) {
            delai = calcDelai(scope.nextControle.data);
          } else {
            delai = 0;
          }
          // replace 'tab' by date_passage || date_avis
          const now = new Date();
          let baseDate = isDatePassage
            ? date_passage
            : scope.cdata.datesDossier.date_avis;
          let mbaseDate = moment(baseDate)
            .add(delai - 1, 'days')
            .add(now.getHours(), 'hours')
            .add(now.getMinutes(), 'minutes');
          tab = mbaseDate;

          let m = moment(tab);

          if (m.format('m') >= 0 && m.format('m') < 30) {
            m.set({ minute: 0, second: 0, millisecond: 0 });
          } else if (m.format('m') >= 30) {
            m.set({ minute: 30, second: 0, millisecond: 0 });
          }

          m = m.toISOString();
          m = $filter('date')(m, 'yyyy-MM-ddTHH:mm:ss.sssZ');
          scope.nextControle.data.date = m;

          if (moment(tab).format('dddd') === 'Saturday') {
            scope.nextControle.data.date = moment(scope.nextControle.data.date)
              .subtract(1, 'days')
              .toDate();
          } else if (moment(tab).format('dddd') === 'Sunday') {
            scope.nextControle.data.date = moment(scope.nextControle.data.date)
              .subtract(2, 'days')
              .toDate();
          }
        });

        //Afficher ou Cacher une filiere
        scope.toggleFiliereOnDossier = (filiere, index) => {
          let show = false;
          let first_element = false;
          scope.reportTree.forEach((b) => {
            if (b.label === 'Filières') {
              b.children.forEach((f) => {
                if (f.filiereId === filiere.id) {
                  f.classes.forEach((cc) => {
                    if (
                      cc === 'showTreeBranch' &&
                      filiere.properties.etat !== 'active'
                    ) {
                      f.classes.splice(f.classes.indexOf('showTreeBranch'));
                      f.classes.push('hiddenTreeBranch');
                      show = true;
                    }
                    if (
                      cc === 'hiddenTreeBranch' &&
                      filiere.properties.etat === 'active'
                    ) {
                      f.classes.splice(f.classes.indexOf('hiddenTreeBranch'));
                      first_element = true;
                    }
                  });
                  if (
                    first_element === false &&
                    filiere.properties.etat === 'active'
                  ) {
                    f.classes.push('hiddenTreeBranch');
                  }
                  if (show === false && filiere.properties.etat !== 'active') {
                    f.classes.push('showTreeBranch');
                  }
                }
              });
            }
          });
        };

        // revoyer l'etat du button
        scope.renderDisplayHideFiliere = (filiere, index) => {
          let res = true;

          scope.reportTree.forEach((b) => {
            if (b.label === 'Filières') {
              b.children.forEach((f) => {
                if (f.filiereId === filiere.id) {
                  f.classes.forEach((cc) => {
                    if (cc === 'showTreeBranch') {
                      res = false;
                    }
                    if (
                      cc === 'hiddenTreeBranch' &&
                      filiere.properties.etat === 'active'
                    ) {
                      res = false;
                    }
                  });
                }
              });
            }
          });

          if (filiere.properties.etat === 'active') {
            res = !res;
          }
          return res;
        };

        scope.listeDesVilles =
          BacAppFactory.appCfg.main.infosSpancListeVillesCfg;

        const liste_ville_filter = [];
        scope.liste_ville = [];
        BacAppFactory.getdossier_villes().then((res) => {
          res.data.forEach((v) => {
            const v_upper = v.charAt(0).toUpperCase() + v.slice(1);
            scope.liste_ville.push(v_upper);
            liste_ville_filter.push({
              key: v,
              label: v_upper,
            });
          });

          liste_ville_filter.unshift({
            key: '',
            label: 'Toutes villes confondues',
          });
        });

        // prepare filtre sur les statuts/avis
        const copyAvisCtrl = [];
        for (let i in scope.choixStatutRDV) {
          copyAvisCtrl.push({
            label: scope.choixStatutRDV[i].label,
            type_controle: 'Statut du RDV',
          });
        }
        for (let j in scope.avisCtrl) {
          copyAvisCtrl.push(scope.avisCtrl[j]);
        }

        let userslist = [];
        UsersFactory.getactiveusers().then((res) => {
          userslist = res.data;
        });
        /**
         * set default controle agent
         */
        let setDefaultControleAgent = () => {
          scope.newControle.agent = '';
          scope.newControle.agent_name = '';
          if (scope.currentControles && scope.currentControles.length) {
            scope.currentControles.forEach((controle) => {
              if (
                scope.newControle &&
                (!scope.newControle.agent || scope.newControle.agent === '')
              ) {
                userslist.forEach((user) => {
                  if (user.login === controle.properties.agent) {
                    scope.newControle.agent = controle.properties.agent;
                    scope.newControle.agent_name =
                      user.name + ' ' + user.vorname;
                  }
                });
              }
            });
          }
          if (
            scope.newControle.agent === '' &&
            $rootScope.xgos.user.login !== 'root'
          ) {
            scope.newControle.agent = $rootScope.xgos.user.login;
            scope.newControle.agent_name =
              $rootScope.xgos.user.name + ' ' + $rootScope.xgos.user.vorname;
          }
        };

        /**
         * open controle externe dialog
         */
        scope.controleExternes = [];
        scope.selectcontroleexterne = {};
        scope.listeControlesWhere = "etat = 'ouvert'";

        scope.openControleExterneDialog = () => {
          scope.selectcontroleexterne = {};
          gaDomUtils.showGlobalLoader();
          scope.controleExterne_Tabs.activeTab = 0;
          BacAppFactory.getcontroledetailexterne('a_traiter').then(
            (res) => {
              scope.controleExternes = res.data;
              gaDomUtils.hideGlobalLoader();
            },
            () => {
              gaDomUtils.hideGlobalLoader();
            }
          );
          ngDialog.open({
            template:
              'js/XG/widgets/ancapp/main/views/modals/modal.controle.externe.html',
            className: 'ngdialog-theme-plain fullScreen nopadding miniclose',
            closeByDocument: false,
            scope: scope,
          });
        };

        /**
         * add controle externe and detail
         * @param id_dossier
         * @param filiere_id
         * @param detail
         */
        let addControleAndDetail = (id_dossier, filiere_id, detail) => {
          // create controle feature collection
          const cFC = {
            type: 'FeatureCollection',
            features: [
              {
                type: 'Feature',
                properties: {
                  type: 'CTRLBC',
                  ref_dossier: id_dossier,
                  statut_facture: 'aucune',
                  etat: 'ouvert',
                  date_saisie_controle: $filter('date')(
                    new Date(),
                    'yyyy-MM-ddTHH:mm:ss.sssZ'
                  ),
                  agent: scope.selectcontroleexterne.agent,
                  subvention: scope.selectcontroleexterne.subvention,
                },
              },
            ],
          };

          BacAppFactory.addcontrole(cFC, id_dossier, filiere_id).then(
            (r) => {
              require('toastr').success('Instruction ajoutée au dossier.', '', {
                positionClass: 'toast-bottom-left',
              });

              BacAppFactory.addcontroledetail(detail, id_dossier, r.data).then(
                (res) => {
                  require('toastr').success(
                    "Informations de l'instruction enregistrées.",
                    '',
                    {
                      positionClass: 'toast-bottom-left',
                    }
                  );
                  BacAppFactory.changeControleExterneDetail(
                    detail.filename,
                    'traite',
                    id_dossier,
                    r.data
                  ).then((res) => {
                    BacAppFactory.getcontroledetailexterne('a_traiter').then(
                      (res) => {
                        scope.controleExternes = res.data;
                      },
                      () => {}
                    );
                  });
                }
              );
            },
            () => {}
          );
        };

        /**
         * appliquer controle externe detail
         */
        let addControleExterne = (res, id_dossier, filiere_id, detail) => {
          BacAppFactory.getcontroles(id_dossier).then((response) => {
            let canAddControle = true;
            if (response.data.features.length) {
              response.data.features.forEach((controle) => {
                if (controle.properties.etat === 'ouvert') {
                  require('toastr').error(
                    'Un instruction est déjà ouvert pour ce dossier.',
                    '',
                    {
                      positionClass: 'toast-bottom-left',
                    }
                  );
                  canAddControle = false;
                }
              });
            } else {
              canAddControle = true;
            }

            if (canAddControle === true) {
              if (
                !response.data.features.length &&
                !filiere_id &&
                res.data.features[0]
              ) {
                filiere_id = res.data.features[0].id;
              }
              // create controle feature collection
              addControleAndDetail(id_dossier, filiere_id, detail);
            }
          });
        };

        /**
         * appliquer controle externe detail
         */
        scope.appliquerControleExterne = (iddossier) => {
          if (controleExternePrepareDialog) {
            controleExternePrepareDialog.close();
          }
          const detail =
            scope.controleExternes[scope.selectcontroleexterne.value];
          let id_dossier = iddossier;
          if (
            scope.selectcontroleexterne.dossier &&
            scope.selectcontroleexterne.dossier.length
          ) {
            id_dossier = scope.selectcontroleexterne.dossier[0].id;
          }

          let filiere_id;
          QueryFactory.data(
            filiereFti.uid,
            "ref_dossier='" + id_dossier + "'"
          ).then((res) => {
            if (res.data.features.length) {
              addControleExterne(res, id_dossier, filiere_id, detail);
            } else {
              const nomFiliere =
                'Filière ' +
                $filter('date')(scope.newFiliere.date, 'dd.MM.yyyy');
            }
          });
        };

        /**
         * open controle externe prepare dialog
         */
        let controleExternePrepareDialog;
        scope.openControleExternePrepareDialog = (index) => {
          scope.userPicker = {};
          scope.selectcontroleexterne.value = index;
          controleExternePrepareDialog = ngDialog.open({
            template:
              'js/XG/widgets/ancapp/main/views/modals/modal.controleExterneAgent.html',
            className: 'ngdialog-theme-plain width500 nopadding miniclose',
            closeByDocument: false,
            scope: scope,
          });
        };
        let dossierForControleExternePrepareDialog;
        scope.openDossierForControleExternePrepareDialog = (index) => {
          scope.ref_dossier_prepare = false;
          if (BacAppFactory.appCfg.main.dossierCfg.numerotation.auto) {
            scope.selectcontroleexterne.ref_dossier = BacAppFactory.getNumeroAuto(
              'TMP_KIS_DOSSIER_ID'
            );
            scope.ref_dossier_prepare = true;
          }

          scope.selectcontroleexterne.value = index;
          //date_creation  etat_dossier  ref_dossier
          dossierForControleExternePrepareDialog = ngDialog.open({
            template:
              'js/XG/widgets/ancapp/main/views/modals/modal.dossierForControleExternePrepare.html',
            className: 'ngdialog-theme-plain width500 nopadding miniclose',
            closeByDocument: false,
            scope: scope,
          });
        };

        /**
         *
         */
        scope.createDossierForControeleExterne = () => {
          gaDomUtils.showGlobalLoader();
          const proprietaire =
            scope.controleExternes[scope.selectcontroleexterne.value]
              .info_generales.proprietaire;
          const adresse_num_rue_extra = proprietaire.adresse_num_rue_extra;

          const pdata = {
            type: 'FeatureCollection',
            features: [
              {
                type: 'Feature',
                properties: {
                  date_creation: $filter('date')(
                    new Date(),
                    'yyyy-MM-ddTHH:mm:ss.sssZ'
                  ),
                  etat_dossier: 'ouvert',
                  ref_dossier: scope.selectcontroleexterne.ref_dossier,
                  adresse_num_rue: proprietaire.adresse_num_rue,
                  adresse_rue: proprietaire.adresse_rue,
                  adresse_ville: proprietaire.adresse_ville,
                  adresse_cp: proprietaire.adresse_cp,
                  adresse_num_rue_extra: adresse_num_rue_extra,
                },
              },
            ],
          };
          BacAppFactory.adddossier(pdata).then(
            (res) => {
              if (res.data === 'already_exist') {
                require('toastr').error(
                  'Cette référence de dossier est déjà utilisée.',
                  '',
                  {
                    positionClass: 'toast-bottom-left',
                  }
                );
              } else {
                //add dossier
                dossierForControleExternePrepareDialog.close();
                require('toastr').success('Dossier enregistré', '', {
                  positionClass: 'toast-bottom-left',
                });
                const id_dossier = res.data[0].id;
                const nomFiliere =
                  'Filière ' +
                  $filter('date')(scope.newFiliere.date, 'dd.MM.yyyy');

                scope.refreshReports();
              }
              gaDomUtils.hideGlobalLoader();
            },
            (reason) => {
              gaDomUtils.hideGlobalLoader();
            }
          );
        };

        /**
         * set agent
         * @type {{}}
         */
        scope.userPicker = {};
        scope.$watch(
          'userPicker.agent',
          function (nap) {
            if (
              nap &&
              angular.isDefined(nap) &&
              angular.isDefined(scope.userPicker)
            ) {
              scope.selectcontroleexterne.agent = nap.login;
              scope.selectcontroleexterne.agent_name =
                nap.name + ' ' + nap.vorname;
            }
          },
          1
        );

        /**
         * dossier table action
         * @type {*[]}
         */
        scope.dossierTableActions = [
          {
            label: 'btn',
            btnclass: 'default',
            cfg: {
              iconOrLabel: 'label',
              label: 'Afficher',
              size: 'btn-xs',
            },
          },
        ];
        /**
         * open dossier
         * @param expr
         * @param dossier
         */
        scope.clickOnDossier = (expr, dossier) => {
          scope.editReport(dossier, false, false);
        };

        /**
         * remove controle externe detail
         * @param v
         * @param index
         */
        scope.removeControleExterneDetail = (v, index) => {
          const ans = confirm(
            'Êtes-vous sur de supprimer ce instruction externe ?'
          );
          if (ans) {
            BacAppFactory.changeControleExterneDetail(
              v.filename,
              'annule'
            ).then((res) => {
              BacAppFactory.getcontroledetailexterne('a_traiter').then(
                (res) => {
                  scope.controleExternes = res.data;
                }
              );
            });
          }
        };

        let activeTab = 0;

        scope.controleExterneTabs = [
          {
            title: 'À traiter',
            key: 'a_traiter',
            content:
              'js/XG/widgets/ancapp/main/views/controle_habitant/a_traiter.html',
          },
          {
            title: 'Traité',
            key: 'traite',
            content:
              'js/XG/widgets/ancapp/main/views/controle_habitant/traite.html',
          },
          {
            title: 'Annulé',
            key: 'annule',
            content:
              'js/XG/widgets/ancapp/main/views/controle_habitant/annule.html',
          },
        ];
        scope.controleExterne_Tabs = {};
        scope.controleExterne_Tabs.activeTab = activeTab;

        /**
         * set tab
         */
        scope.$watch(
          'controleExterne_Tabs.activeTab',
          (tab) => {
            if (tab || tab === 0) {
              let type = 'a_traiter';
              if (tab === 1) type = 'traite';
              if (tab === 2) type = 'annule';
              BacAppFactory.getcontroledetailexterne(type).then((res) => {
                scope.controleExternes = res.data;
              });
            }
          },
          1
        );

        /**
         * open report dialog
         * @param dossier_id
         */
        scope.open_report_dialog = (dossier_id, id_controle) => {
          console.log(id_controle);
          gaDomUtils.showGlobalLoader();
          BacAppFactory.getdossier(dossier_id).then((res) => {
            gaDomUtils.hideGlobalLoader();
            scope.editReport(res.data.features[0], false, id_controle);
          });
        };

        /**
         * render user true name
         * @param login
         */
        scope.renderTrueUserName = (login) => {
          let res = login;
          if (userslist && userslist.length) {
            userslist.forEach((user) => {
              if (user.login === login) {
                res = user.name + ' ' + user.vorname;
              }
            });
          }
          return res;
        };

        /**
         * open controle habitant form
         */
        scope.openControleHabitantForm = () => {
          window.open(
            $location.absUrl().split('#')[0] +
              'ext/conception_anc/controle.html?portal=' +
              $location.search().portal +
              '&app=' +
              $location.search().app
          );
        };

        /**
         * active
         * @param v
         */
        scope.activerAnnuleControleHabitant = (v) => {
          const ans = confirm(
            'Êtes-vous sur de vouloir activer ce instruction habitant ?'
          );
          if (ans) {
            BacAppFactory.activecontroledetailexterne(v.filename).then(
              (res) => {
                BacAppFactory.getcontroledetailexterne('annule').then(
                  (res) => {
                    scope.controleExternes = res.data;
                  },
                  () => {}
                );
              }
            );
          }
        };

        scope.controleFTI = FeatureTypeFactory.getFeatureByNameAndDatastore(
          BacAppFactory.appCfg.main.datastore,
          'kis_bac_dossier_controle'
        );

        scope.filiereFTI = FeatureTypeFactory.getFeatureByNameAndDatastore(
          BacAppFactory.appCfg.main.datastore,
          'kis_anc_dossier_filiere'
        );

        scope.filiereElementFTI = FeatureTypeFactory.getFeatureByNameAndDatastore(
          BacAppFactory.appCfg.main.datastore,
          'kis_anc_dossier_filiere_element'
        );

        scope.etablissementFti = FeatureTypeFactory.getFeatureByNameAndDatastore(
          BacAppFactory.appCfg.main.datastore,
          'kis_bac_etablissement'
        );

        scope.filiereElementSFTI = FeatureTypeFactory.resources.featuretypes
          .map((x) => {
            if (x.name.startsWith('kis_anc_ef_')) return x;
          })
          .filter((x) => {
            if (x) return x;
          });

        scope.showSearch = true;

        if (
          scope.dossierFti !== null &&
          scope.controleFTI !== null &&
          scope.dossierFti.inElasticSearch &&
          scope.controleFTI.inElasticSearch
        ) {
          scope.reportTabs.push({
            title: 'Filtres avancés',
            key: 'advanced_filters_jointure',
          });
        }

        scope.visibleSearch = function () {
          scope.showSearch = !scope.showSearch;
        };

        scope.$on('resultelastic', function (event, q, t, r) {
          scope.searchquerydb = q;
          scope.searchType = t;
          scope.searchconfig = r;
          scope.showSearch = false;
        });

        scope.changedReportTabs = function () {
          if (scope.reportTabs.activeTab === 11) scope.showSearch = true;
        };

        // ///////////Fonctions pour prise de RDV
        scope.createCtrlAndWaitForRDV = function () {
          // /Creation d'un controle vide
          // bloqueChangementAvis puisque maintenant le controle reste
          // affiché en fond une fois l'avis donné
          $rootScope.$broadcast('bloqueChangementAvis', {});
          scope.appliquerAvisControle();
        };

        ConfigFactory.get('BAC', 'calendar').then((res) => {
          if (res.data != '') {
            scope.calendarConfig = res.data;
          }
        });

        function avertir(mess) {
          swal({
            title: mess,
            type: 'warning',
            showCancelButton: false,
            confirmButtonColor: '#DD6B55',
          });
        }

        scope.rendezVousIsPossible = (ctrl) => {
          let iEt, et, typeEvent;
          // -- Si pas de configuration:
          // -- pas de contrôle interdit en prise de rendez-vous.
          if (scope.calendarConfig == undefined) {
            return true;
          }

          // -- Recherche du type d'événment correspondant au contrôle
          // -- dans la configuration de l'agenda.
          const res = kisCalendarFactory.getEventFromTypeDeControle(
            ctrl,
            calendarEventTypes
          );
          typeEvent = res.typeEvent;
          for (iEt = 0; iEt < scope.calendarConfig.eventTypes.length; iEt++) {
            et = scope.calendarConfig.eventTypes[iEt];
            if (typeEvent == et.type_id) {
              // -- Le type d'événement correspondant au côontrle est trouvé,
              // -- on sait si le rendez-vous est autorisé ou non pour ce
              // contrôle.
              return et.rdvIsPossible;
            }
          }
          // -- Type de contrôle sans correspondance !!!!!!
          return true;
        };

        function getNumDossier(idDossier) {
          let iDossier;
          for (iDossier = 0; iDossier < scope.res.length; iDossier++) {
            if (scope.res[iDossier].id == idDossier) {
              return scope.res[iDossier].properties.ref_dossier;
            }
          }
          return '?';
        }

        function validateDelaiPriseDeRdv() {
          if (!scope.paramData.delai) {
            require('toastr').success(
              'La valeur du champ délai a été modifiée pour être supérieure ou égale à 30',
              '',
              { positionClass: 'toast-top-right' }
            );
            scope.paramData.delai = 30;
          }
          return true;
        }

        function prepareAndOpenRdvAuto(res, fromControle) {
          let fullMess = '';
          let mess;
          const ctrls = res.data.features;
          for (let j = 0; j < ctrls.length; j++) {
            const obj = {
              ctrl: [ctrls[j]],
            };
            // -- Vérifier si le type de contrôle appartient à la liste
            // -- des types d'événements pour lesquels
            // -- un rendez-vous peut être pris.
            if (scope.rendezVousIsPossible(ctrls[j]))
              scope.ctrlDossiers.push(obj);
            else {
              // -- Message des contrôles non autorisés en rendez-vous
              if (fullMess == '')
                fullMess = 'Rendez-vous non autorisé pour le(s) dossier(s):';
              fullMess +=
                '\n- ' + getNumDossier(ctrls[j].properties.ref_dossier);
            }
          }
          if (fullMess != '') {
            avertir(fullMess);
          }
          let doss;
          for (let k = 0; k < scope.ctrlDossiers.length; k++) {
            if (!fromControle) {
              const ref = scope.ctrlDossiers[k].ctrl[0].properties.ref_dossier;
              doss = getDossierByRefCtrl(ref);
            } else {
              doss = angular.copy(scope.currentReport);
            }

            scope.ctrlDossiers[k].doss = doss;
          }
          gaDomUtils.hideGlobalLoader();
          $rootScope.calendar.agentvisible = true;
          if (scope.paramData.agent !== undefined) {
            scope.agentctrl = scope.paramData.agent.login;
          } else {
            scope.paramData.agent = $rootScope.xgos.user.login;
            scope.agentctrl = $rootScope.xgos.user.login;
          }

          if (scope.ctrlDossiers.length != 0) {
            scope.rdvAuto = ngDialog.open({
              template:
                'js/XG/widgets/ancapp/main/views/calendrierRdvsAuto2.html',
              id: 'agnda',
              className: 'ngdialog-theme-plain width1200 miniclose nopadding',
              closeByDocument: false,
              scope: scope,
              preCloseCallback: () => {
                $rootScope.$broadcast('kis_calendar_event_changed');
              },
            });
          }
        }

        /**
         * [actionPriseRdv action prise de rdv automatique]
         *
         * @return {[type]} [description]
         */
        scope.actionPriseRdv = (fromControle) => {
          scope.fromControle = fromControle;
          scope.openParametrageVisites();
          gaDomUtils.showGlobalLoader();
          scope.ctrlDossiers = [];
          let ids = [];
          if (fromControle) {
            ids.push(scope.currentReport.id);
          } else {
            // depuis liste des dossiers
            const tab = scope.res;
            for (let i = 0; i < tab.length; i++) {
              ids.push(tab[i].id);
            }
          }

          const promise = BacAppFactory.getActifsControles(ids).then((res) => {
            // creation depuis workflow lorsqu'on vient de cloturer un controle
            if (
              res.data.features != undefined &&
              !res.data.features.length &&
              fromControle &&
              scope.nextControle &&
              scope.nextControle.data
            ) {
              const ans = confirm(
                'Voulez-vous créer le prochain contrôle de type ' +
                  scope.nextControle.data.type +
                  '?'
              );
              if (ans) {
                addNewControle(avisControleDialog);
              }
              gaDomUtils.hideGlobalLoader();
              return;

              // erreur aucun controle, depuis la liste des dossiers
            } else if (!res.data.features.length && !fromControle) {
              require('toastr').error(
                "Aucun contrôle n'est ouvert parmi les dossiers sélectionnés.",
                '',
                {
                  positionClass: 'toast-bottom-left',
                }
              );
              gaDomUtils.hideGlobalLoader();
              return;
            } else {
              prepareAndOpenRdvAuto(res, fromControle);
            }
          });
        };

        /**
         * [openParametrageVisites parametrage pour prise de rdv auto]
         *
         * @return {[type]} [description]
         */
        scope.openParametrageVisites = () => {
          let date;
          scope.delai = {};
          date = new Date();

          let date_fin;
          date_fin = new Date(date);

          if (!scope.paramData) scope.paramData = {};

          let agent =
            $rootScope.xgos.user.login !== 'root' ? $rootScope.xgos.user : {};
          date = date;

          let promise = UsersFactory.getactiveuserslight();
          promise.then((res) => {
            let gusers = res.data;

            scope.agentCalendar = {
              value: {},
            };

            let heureDebutMatin = new Date(date);
            if (localStorage.getItem('rdvHeureDebut1')) {
              const hours = localStorage.getItem('rdvHeureDebut1');
              date.setHours(hours, 0);
              heureDebutMatin.setHours(hours, 0);
            } else {
              localStorage.setItem('rdvHeureDebut1', 8);
              heureDebutMatin.setHours(8, 0);
            }

            let heureFinMatin = new Date(date);
            if (localStorage.getItem('rdvHeureFin1')) {
              const hours = localStorage.getItem('rdvHeureFin1');
              heureFinMatin.setHours(hours, 0);
            } else {
              localStorage.setItem('rdvHeureFin1', 12);
              heureFinMatin.setHours(12, 0);
            }

            let heureDebutApresmidi = new Date(date);
            if (localStorage.getItem('rdvHeureDebut2')) {
              const hours = localStorage.getItem('rdvHeureDebut2');
              heureDebutApresmidi.setHours(hours, 0);
            } else {
              localStorage.setItem('rdvHeureDebut2', 14);
              heureDebutApresmidi.setHours(14, 0);
            }

            let heureFinApresmidi = new Date(date);
            if (localStorage.getItem('rdvHeureFin2')) {
              const hours = localStorage.getItem('rdvHeureFin2');
              heureFinApresmidi.setHours(hours, 0);
            } else {
              localStorage.setItem('rdvHeureFin2', 18);
              heureFinApresmidi.setHours(18, 0);
            }

            let delaix;
            if (localStorage.getItem('rdvDelai')) {
              delaix = parseInt(localStorage.getItem('rdvDelai'));
              scope.delai.delaiToTest = delaix;
            } else {
              delaix = 60;
              scope.delai.delaiToTest = delaix;
            }
            let agent;
            if (localStorage.getItem('rdvAgent')) {
              for (let i = 0; i < gusers.length; i++) {
                if (gusers[i].login === localStorage.getItem('rdvAgent')) {
                  agent = gusers[i];
                }
              }
            } else {
              agent =
                $rootScope.xgos.user.login !== 'root'
                  ? $rootScope.xgos.user
                  : '';
            }
            function getDefaultTimetable() {
              return {
                matinee: true,
                apresmidi: true,
                dateDebut1: angular.copy(heureDebutMatin),
                dateFin1: angular.copy(heureFinMatin),
                dateDebut2: angular.copy(heureDebutApresmidi),
                dateFin2: angular.copy(heureFinApresmidi),
              };
            }
            scope.paramData = {
              delai: parseInt(delaix),
              agent: agent,
              date: date,
              date0: date,
              dateDebut1: heureDebutMatin,
              dateFin1: heureFinMatin,
              dateDebut2: heureDebutApresmidi,
              dateFin2: heureFinApresmidi,
              fin_rdv: date_fin,
              matinee: true,
              apresmidi: true,
              set_date_fin: false,
              jours: {
                MONDAY: {},
                TUESDAY: {},
                WEDNESDAY: {},
                THURSDAY: {},
                FRIDAY: {},
                SATURDAY: {},
                SUNDAY: {},
              },
            };
            const days = [
              'MONDAY',
              'TUESDAY',
              'WEDNESDAY',
              'THURSDAY',
              'FRIDAY',
              'SATURDAY',
              'SUNDAY',
            ];

            CalendarFactory.getcalendarworkhours().then((res) => {
              scope.businessHours = res.data.features.map(
                (workingHourFeature) => {
                  const businessDay =
                    scope.paramData.jours[
                      days[workingHourFeature.properties.weekday]
                    ];
                  const feature = workingHourFeature.properties;
                  businessDay.dateDebut1 =
                    getMinDate(feature.am_start, feature.am_end) ||
                    moment('08:00', 'HH:mm');
                  businessDay.dateFin1 =
                    getMaxDate(feature.am_start, feature.am_end) ||
                    moment('12:00', 'HH:mm');
                  businessDay.dateDebut2 =
                    getMinDate(feature.pm_start, feature.pm_end) ||
                    moment('13:00', 'HH:mm');
                  businessDay.dateFin2 =
                    getMaxDate(feature.pm_start, feature.pm_end) ||
                    moment('18:00', 'HH:mm');
                  businessDay.matinee = workingHourFeature.properties.active;
                  businessDay.apresmidi = workingHourFeature.properties.active;
                }
              );
            });
          });
        };

        /**
         * [saveParametresVisites recuperation des infos necessaires a la prise
         * de rdv auto]
         *
         * @return {[type]} [description]
         */
        scope.saveParametresVisites = () => {
          const date0 = angular.copy(scope.paramData.date);
          date0.setSeconds(0);

          const jours = angular.copy(scope.paramData.jours);
          for (let jour in jours) {
            let dateDebut1 = angular.copy(date0);

            dateDebut1.setHours(
              new Date(scope.paramData.jours[jour].dateDebut1).getHours()
            );
            dateDebut1.setMinutes(
              new Date(scope.paramData.jours[jour].dateDebut1).getMinutes()
            );
            dateDebut1.setSeconds(0);
            jours[jour].dateDebut1 = dateDebut1.getTime();

            let dateFin1 = angular.copy(date0);
            dateFin1.setHours(
              new Date(scope.paramData.jours[jour].dateFin1).getHours()
            );
            dateFin1.setMinutes(
              new Date(scope.paramData.jours[jour].dateFin1).getMinutes()
            );
            dateFin1.setSeconds(0);
            jours[jour].dateFin1 = dateFin1.getTime();

            let dateDebut2 = angular.copy(date0);

            dateDebut2.setHours(
              new Date(scope.paramData.jours[jour].dateDebut2).getHours()
            );
            dateDebut2.setMinutes(
              new Date(scope.paramData.jours[jour].dateDebut2).getMinutes()
            );

            dateDebut2.setSeconds(0);
            jours[jour].dateDebut2 = dateDebut2.getTime();

            let dateFin2 = angular.copy(date0);
            dateFin2.setHours(
              new Date(scope.paramData.jours[jour].dateFin2).getHours()
            );
            dateFin2.setMinutes(
              new Date(scope.paramData.jours[jour].dateFin2).getMinutes()
            );
            dateFin2.setSeconds(0);
            jours[jour].dateFin2 = dateFin2.getTime();
          }

          scope.parametresVisites = {
            delai: scope.paramData.delai,
            agent: scope.paramData.agent.login,
            date0: date0.getTime(),
            dossiers: [],
            fin_rdv: angular.isDefined(scope.paramData.fin_rdv)
              ? scope.paramData.fin_rdv.getTime()
              : null,
            set_date_fin: scope.paramData.set_date_fin,
            interval: jours,
          };
          localStorage.setItem('rdvDelai', scope.parametresVisites.delai);
          localStorage.setItem('rdvAgent', scope.parametresVisites.agent);
        };

        scope.cancelParametresVisites = () => {
          scope.ngDialogParametresVisites.close();
        };

        let getMinutesDiff = (fin_date, debut_date) => {
          fin_date = new Date(fin_date);
          debut_date = new Date(debut_date);
          const date_interval = new Date(fin_date - debut_date);
          date_interval.setMinutes(
            date_interval.getMinutes() + date_interval.getTimezoneOffset()
          );
          const diffMins = date_interval.getHours() * 60;

          return diffMins;
        };

        let getMaxInterval = () => {
          let matinee = 0;
          let apresmidi = 0;
          if (
            angular.isDefined(scope.paramData.matinee) &&
            scope.paramData.matinee
          ) {
            if (
              angular.isDefined(scope.paramData.dateDebut1) &&
              angular.isDefined(scope.paramData.dateFin1)
            ) {
              matinee = getMinutesDiff(
                scope.paramData.dateFin1,
                scope.paramData.dateDebut1
              );
            }
          }

          if (
            angular.isDefined(scope.paramData.apresmidi) &&
            scope.paramData.apresmidi
          ) {
            if (
              angular.isDefined(scope.paramData.dateDebut2) &&
              angular.isDefined(scope.paramData.dateFin2)
            ) {
              apresmidi = getMinutesDiff(
                scope.paramData.dateFin2,
                scope.paramData.dateDebut2
              );
            }
          }

          return matinee > apresmidi ? matinee : apresmidi;
        };

        let setDelaiLocalStorage = (value) => {
          let disablePlanifRdv = true;
          if (angular.isDefined(value) && value !== null) {
            if (Number.isInteger(value) && value > 0) {
              const maxInt = getMaxInterval();
              if (maxInt >= value) {
                scope.paramData.delai = value;
                localStorage.setItem('rdvDelai', scope.paramData.delai);
                disablePlanifRdv = false;
                $rootScope.$broadcast('disableClicEvent', disablePlanifRdv);
              } else {
                const horaire = {};
                horaire.hMax = Math.trunc(maxInt / 60);
                horaire.minMax = maxInt % 60;
                horaire.hMaxSaisie = Math.trunc(value / 60);
                horaire.minMaxSaisie = value % 60;

                horaire.dateMax = new Date();
                horaire.dateMax.setHours(
                  horaire.hMaxSaisie,
                  horaire.minMaxSaisie
                );
                horaire.dateMin = new Date();
                horaire.dateMin.setHours(horaire.hMax, horaire.minMax);

                require('toastr').error(
                  'Aucun créneau de ' +
                    moment(horaire.dateMax).format('HH:mm') +
                    " n'est disponible (max. " +
                    moment(horaire.dateMin).format('HH:mm') +
                    ').',
                  'Erreur',
                  {
                    positionClass: 'toast-bottom-left',
                  }
                );
                $rootScope.$broadcast('disableClicEvent', disablePlanifRdv);
              }
            } else {
              require('toastr').error('Délai invalide', 'Erreur', {
                positionClass: 'toast-bottom-left',
              });
            }
          }
          return disablePlanifRdv;
        };

        let testHourForPlanif = (toSet) => {
          let isOk = true;

          if (
            (toSet !== 'rdvHeureDebut1' &&
              !localStorage.getItem('rdvHeureDebut1')) ||
            isNaN(localStorage.getItem('rdvHeureDebut1')) ||
            localStorage.getItem('rdvHeureDebut1') == null
          )
            isOk = false;

          if (
            (toSet !== 'rdvHeureFin1' &&
              !localStorage.getItem('rdvHeureFin1')) ||
            isNaN(localStorage.getItem('rdvHeureFin1')) ||
            localStorage.getItem('rdvHeureFin1') == null
          )
            isOk = false;

          if (
            (toSet !== 'rdvHeureDebut2' &&
              !localStorage.getItem('rdvHeureDebut2')) ||
            isNaN(localStorage.getItem('rdvHeureDebut2')) ||
            localStorage.getItem('rdvHeureDebut2') == null
          )
            isOk = false;

          if (
            (toSet !== 'rdvHeureFin2' &&
              !localStorage.getItem('rdvHeureFin2')) ||
            isNaN(localStorage.getItem('rdvHeureFin2')) ||
            localStorage.getItem('rdvHeureFin2') == null
          )
            isOk = false;

          return isOk;
        };

        let getChoixStatutRDV = () => {
          return [
            {
              value: 'absent',
              label: 'Absent',
            },
            {
              value: 'refus',
              label: 'Refus de visite',
            },
            {
              value: 'npai',
              label: "N'habite pas à l'adresse indiquée",
            },
            {
              value: 'present',
              label: 'Présent',
            },
            {
              value: 'reporte',
              label: 'Reporté',
            },
            {
              value: 'annule',
              label: 'Annulé',
            },
          ];
        };

        /**
         * Lancement du webservice de prise de rdv
         */
        let doPriseRdv = (fixedSlot) => {
          // aucun agent specifie
          if (!angular.isDefined(scope.paramData.agent)) {
            require('toastr').error(
              "Veuillez sélectionner l'agent concerné",
              'Erreur',
              {
                positionClass: 'toast-bottom-left',
              }
            );
            return;
          }

          gaDomUtils.showGlobalLoader();
          scope.saveParametresVisites();
          $timeout(() => {
            scope.parametresVisites.dossiers = getDossierListIds();
            const dataToSend = angular.copy(scope.parametresVisites);
            dataToSend.fixedSlot = fixedSlot;
            CalendarFactory.priseRdvsAuto(dataToSend)
              .then(() => handlePriseRdvSuccess())
              .catch(() =>
                CalendarFactory.priseRdvsAuto(dataToSend)
                  .then(() => handlePriseRdvSuccess())
                  .catch(() => {
                    require('toastr').error(
                      'Erreur lors de la planification des RDV',
                      '',
                      { positionClass: 'toast-bottom-left' }
                    );
                    gaDomUtils.hideGlobalLoader();
                  })
              );
          });
        };

        function _confirm(mess, okCallback) {
          return swal(
            {
              title: mess,
              type: 'warning',
              showCancelButton: true,
              confirmButtonColor: '#DD6B55',
              confirmButtonText: $filter('translate')('common.yes'),
              cancelButtonText: $filter('translate')('common.no'),
              closeOnConfirm: true,
            },
            okCallback
          );
        }

        scope.getDateDebutFirstAvailableHour = () => {
          const jours = angular.copy(scope.paramData.jours);
          const weekDays = moment.weekdays();
          const debutDay = moment(angular.copy(scope.paramData.date)).format(
            'dddd'
          );
          const orderedWeekdays = weekDays
            .splice(
              weekDays.indexOf(debutDay),
              weekDays.length - weekDays.indexOf(debutDay)
            )
            .concat(weekDays)
            .map((day) => day.toUpperCase());
          const hour = orderedWeekdays.reduce((finalHour, day) => {
            if (finalHour || !jours[day]) {
              return finalHour;
            }
            const intervalDay = jours[day];
            if (!intervalDay.matinee && !intervalDay.apresmidi) {
              return finalHour;
            }
            finalHour =
              intervalDay.matinee &&
              isDelayValidForIntervals(
                intervalDay.dateDebut1,
                intervalDay.dateFin1,
                scope.paramData.delai
              )
                ? intervalDay.dateDebut1
                : isDelayValidForIntervals(
                    intervalDay.dateDebut2,
                    intervalDay.dateFin2,
                    scope.paramData.delai
                  )
                ? intervalDay.dateDebut2
                : false;
            return finalHour;
          }, false);
          function isDelayValidForIntervals(start, end, delai) {
            if (!start || !end) {
              return false;
            }
            return moment(start).add(delai, 'minutes').diff(moment(end)) <= 0;
          }
          return hour;
        };

        /**
         * [priseRdvsAuto prise de rdv automatique]
         *
         * @return {[type]} [description]
         */
        scope.priseRdvsAuto = () => {
          validateDelaiPriseDeRdv();

          scope.planifProchainControle = false;
          let hour = scope.getDateDebutFirstAvailableHour();
          if (!hour) {
            require('toastr').error(
              'Le délai de rendez-vous est invalide !',
              '',
              { positionClass: 'toast-top-right' }
            );
            return;
          }
          if (scope.verifyIfEventExists()) {
            _confirm(
              'Certains contrôles ont déja des évenements planifiés. ' +
                'Voulez-vous repositionner les évenements existants à partir de ' +
                $filter('date')(hour, 'HH:mm') +
                ' ?',
              (isConfirm) => {
                if (!isConfirm) {
                  return false;
                }
                if (angular.isUndefined(scope.parametresVisite)) {
                  scope.parametresVisites = {};
                }
                const tabDossiers = [];
                for (let i = 0; i < scope.ctrlDossiers.length; i++) {
                  tabDossiers.push(scope.ctrlDossiers[i].doss.id);
                }
                scope.parametresVisites.dossiers = tabDossiers;

                CalendarFactory.cancelRdvsAuto(scope.parametresVisites)
                  .then(() => doPriseRdv())
                  .catch((err) => {
                    err.stack;
                  });
              }
            );
          } else {
            _confirm(
              'Voulez vous lancer la planification des rendez vous à partir de ' +
                $filter('date')(hour, 'HH:mm') +
                ' ?',
              (isConfirm) => {
                if (isConfirm) doPriseRdv();
              }
            );
          }
        };

        /**
         * [cancelRdvsAuto annuler la prise de rdv automatique]
         *
         * @return {[type]} [description]
         */
        scope.cancelRdvsAuto = () => {
          _confirm(
            'Êtes vous sûr de vouloir supprimer les évenements existants ?',
            (isConfirm) => {
              if (isConfirm) {
                scope.saveParametresVisites();
                const tabDossiers = [];
                for (let i = 0; i < scope.ctrlDossiers.length; i++) {
                  tabDossiers.push(scope.ctrlDossiers[i].doss.id);
                }
                scope.parametresVisites.dossiers = tabDossiers;
                CalendarFactory.cancelRdvsAuto(scope.parametresVisites).then(
                  (res1) => {
                    const data = {
                      agent: scope.parametresVisites.agent,
                    };
                    $rootScope.$broadcast(
                      'kis_calendar_eventAgent_refresh',
                      data
                    );
                    $timeout(() => {
                      scope.refreshCtrlsPriseRdv();
                    }, 3000);
                    scope.refreshReports();
                  }
                );
              }
            }
          );
        };

        /* prise de rdv depuis clic */
        $rootScope.$on('getHeureDebut', (event, data) => {
          scope.heureDeb = true;
          const dateT = data.heureDebut.split(':');
          const hr = parseInt(dateT[0]);
          const min = parseInt(dateT[1]);

          scope.paramData.date0 = new Date(scope.paramData.dateFin1);
          scope.paramData.date0 = new Date(scope.paramData.date0.setHours(hr));
          scope.paramData.date0.setMinutes(min);
          scope.paramData.date0.setSeconds(0);
          scope.paramData.date = data.debut.toDate();
          scope.rdvFromClic = true;
          doPriseRdv(data.fixedSlot);
        });

        function FindByAttributeValue(attribute, value, element_type) {
          element_type = element_type || '*';
          const All = document.getElementsByTagName(element_type);
          for (let i = 0; i < All.length; i++) {
            if (All[i].getAttribute(attribute) === value) {
              return All[i];
            }
          }
        }

        // changement de date principale dans la prise de RDV
        scope.$watch('paramData.date', (curr, prev) => {
          if (angular.isDate(curr) && angular.isDate(curr) && curr !== prev) {
            const mc = uiCalendarConfig.calendars['kisCalendar'];
            if (angular.isDefined(mc)) {
              uiCalendarConfig.calendars['kisCalendar'].fullCalendar(
                'changeView',
                'agendaDay'
              );
              uiCalendarConfig.calendars['kisCalendar'].fullCalendar(
                'gotoDate',
                curr
              );
            }
          }
        });

        function handlePriseRdvSuccess() {
          $rootScope.$broadcast('kis_calendar_eventAgent_refresh', {
            agent: scope.parametresVisites.agent,
          });

          gaDomUtils.hideGlobalLoader();
          gaDomUtils.showLocalLoader('.controle_concernes');

          $timeout(() => {
            scope.refreshCtrlsPriseRdv(scope.fromControle);
            scope.heureDeb = false;
          }, 2000);

          scope.refreshReports();
        }

        /**
         * [localiseEvent localise and highlight event]
         *
         * @param {[type]}
         *            date [description]
         * @param {[type]}
         *            idControle [description]
         * @return {[type]} [description]
         */
        scope.localiseEvent = (date, idControle) => {
          uiCalendarConfig.calendars['kisCalendar'].fullCalendar(
            'changeView',
            'agendaDay'
          );
          uiCalendarConfig.calendars['kisCalendar'].fullCalendar(
            'gotoDate',
            date
          );

          CalendarFactory.getEventByControl(idControle).then(
            (res1) => {
              $timeout(() => {
                const el = $(
                  FindByAttributeValue('idEvent', res1.data.features[0].id, 'a')
                );
                // scroll jusqu'au controle
                angular.element('.fc-time-grid-container.fc-scroller').animate(
                  {
                    scrollTop: el.position().top - 25,
                  },
                  1000,
                  () => {
                    el.addClass('highlightEvent');
                    $timeout(() => {
                      el.removeClass('highlightEvent');
                    }, 7000);
                  }
                );
              });
            },
            () => {
              require('toastr').error(
                'Erreur lors de la récupération du calendrier, est-il activé pour le portail ?',
                '',
                {
                  positionClass: 'toast-bottom-left',
                }
              );
            }
          );
        };

        /**
         * [verifyIfEventExists verifier si event existe par verification de
         * date de passage du controle]
         *
         * @return {[type]} [description]
         */
        scope.verifyIfEventExists = () => {
          let exists = false;
          for (let i = 0; i < scope.ctrlDossiers.length; i++) {
            if (
              scope.ctrlDossiers[i].ctrl[0].properties.date_passage_rdv != null
            ) {
              exists = true;
              break;
            }
          }
          return exists;
        };

        /**
         * [refreshCtrlsPriseRdv rafraichir la liste des contrôles]
         *
         * @return {[type]} [description]
         */
        scope.refreshCtrlsPriseRdv = () => {
          let promise;
          scope.newCtrls = [];

          const ids = scope.parametresVisites
            ? scope.parametresVisites.dossiers.toString()
            : getDossierListIds().toString();
          promise = BacAppFactory.getActifsControles(ids).then(
            (res) => {
              if (!res.data.features.length) {
                require('toastr').error(
                  "Aucun contrôle n'est ouvert parmi les dossiers sélectionnés.",
                  '',
                  {
                    positionClass: 'toast-bottom-left',
                  }
                );
                return;
              }

              const ctrls = res.data.features;
              for (let j = 0; j < ctrls.length; j++) {
                const newctrl = ctrls[j];
                for (let k = 0; k < scope.ctrlDossiers.length; k++) {
                  if (
                    scope.ctrlDossiers[k].doss.id ===
                    newctrl.properties.ref_dossier
                  ) {
                    scope.ctrlDossiers[k].ctrl = [newctrl];
                    break;
                  }
                }
              }

              // Trigger refresh to get new date rdv
              if (angular.isDefined(scope.fromControle) && scope.fromControle) {
                scope.reportTree_handle(scope.currentBranch);
              }

              gaDomUtils.removeLocalLoader('.controle_concernes');
            },
            () => {
              gaDomUtils.removeLocalLoader('.controle_concernes');
            }
          );
        };

        function getDossierListIds() {
          return (scope.ctrlDossiers || []).map(
            (dossier) => dossier && dossier.doss.id
          );
        }

        scope.$watch(
          'ctrlDossiers',
          (model) => {
            scope.modelAsJson = angular.toJson(model, false);
          },
          false
        );

        $rootScope.$on('gcDataTableGetDataFti', (ev, data) => {
          if (data.params.count()) {
            localStorage.setItem('gcDataTableCount', data.params.count());
          }
        });

        // rdv choisi par defaut
        scope.action = {
          selectedAction: 'rdv',
        };

        let getDossierByRefCtrl = (ref) => {
          let doss;
          for (let j = 0; j < scope.res.length; j++) {
            if (scope.res[j].id === ref) {
              doss = scope.res[j];
              break;
            }
          }
          return doss;
        };

        function addNewControle(avisControleDialog) {
          if (angular.isDefined(avisControleDialog)) {
            avisControleDialog.close();
          }
          const dateSaisie = $filter('date')(
            new Date(),
            'yyyy-MM-ddTHH:mm:ss.sssZ'
          );
          scope.newControle = {
            agent: scope.currentControle.properties.agent,
            date_saisie_controle: dateSaisie,
            est_dernier_controle_cloture: false,
            etat: 'ouvert',
            ref_dossier: scope.currentReport.id,
            reference_filiere: '',
            type: scope.nextControle.data.type,
            //date_max: scope.nextControle.data.delai
            //  ? scope.nextControle.data.dateMax
            //  : null,
          };
          scope.addControleToDossier(null, true, true);
        }

        function getMinDate(date1, date2) {
          return !date1 || moment(date1).diff(moment(date2)) > 0
            ? date2
            : date1;
        }
        function getMaxDate(date1, date2) {
          return !date1 || moment(date1).diff(moment(date2)) < 0
            ? date2
            : date1;
        }

        /*******************************************************************************************
         *******************************************************************************************
         *******************************************************************************************
         *******************************************************************************************
         *
         *
         *
         *  SPECIFIQUE BAC
         *
         *
         *
         *******************************************************************************************
         *******************************************************************************************
         *******************************************************************************************
         ******************************************************************************************/
        let dossierBranchementFti = angular.copy(
          FeatureTypeFactory.getFeatureByNameAndDatastore(
            BacAppFactory.appCfg.main.datastore,
            'kis_bac_branchement_dossier'
          )
        );

        function sortLayersByIndex(layer1, layer2) {
          const index1 = layer1.get('index');
          const index2 = layer2.get('index');
          if (index1 == null) return -1;
          else if (index2 == null) return 1;
          else if (index1 < index2) return -1;
          return 1;
        }

        function addOperationalLayer(layer) {
          if (layer.fti.type === 'esri' && layer.fti.geographic) {
            gclayers.addOperationalLayerESRI(layer);
          } else if (layer.fti.geographic && layer.fti.published) {
            gclayers.addOperationalLayerg2c(layer);
          }
        }

        scope.go = (extent) => {
          const size = scope.map.getSize();
          const view = scope.map.getView();

          view.fit(extent, size);
        };

        panelsManager.init();
        scope.panelsManager = panelsManager;

        /**
         * initMap
         * init branchements Map
         */

        let watchBranchementDisplay;
        function getMainMapModel(res) {
          if (res.data !== '') {
            let mappedLayers = [];
            let noMappedLayers = [];
            FeatureTypeFactory.resources.featuretypes.forEach((fType) => {
              if (
                fType &&
                fType.uid &&
                fType.uid.indexOf('kis_anc_ef') === -1
              ) {
                const deleteIndex = res.data
                  .map((x) => {
                    return x.fti.uid;
                  })
                  .indexOf(fType.uid);
                if (deleteIndex !== -1) {
                  const t = res.data[deleteIndex];
                  const modelfti = fType;
                  if (modelfti != null) {
                    ///////
                    t.fti = modelfti;
                    t.theme = fType.theme;
                    const l = gcWMS.getOlLayerFromMapModelElement(t);
                    mappedLayers.push(l);
                  }
                } else {
                  if (fType.type === 'esri' && fType.geographic) {
                    const l = gcWMS.getOlLayerFromFeaturetypeInfo(fType, ind);
                    noMappedLayers.push(l);
                  } else if (fType.geographic && fType.published) {
                    const l = gcWMS.getOlLayerFromFeaturetypeInfo(fType, ind);
                    noMappedLayers.push(l);
                  }
                }
              }
            });

            mappedLayers = mappedLayers.sort(sortLayersByIndex);
            for (let i = 0; i < mappedLayers.length; i++)
              addOperationalLayer(mappedLayers[i]);
            for (let i = 0; i < noMappedLayers.length; i++)
              addOperationalLayer(noMappedLayers[i]);
          } else {
            // AUcun map model alors on ajoute tous les composants
            //console.log("Pas de config  " +FeatureTypeFactory.resources.featuretypes);
            let ind = 0;
            FeatureTypeFactory.resources.featuretypes.forEach((fType) => {
              if (
                fType &&
                fType.uid &&
                fType.uid.indexOf('kis_anc_ef') === -1
              ) {
                if (fType.geographic && fType.published) {
                  const l = gcWMS.getOlLayerFromFeaturetypeInfo(fType, ind);
                  if (fType.type === 'esri' && fType.geographic) {
                    gclayers.addOperationalLayerESRI(l);
                  } else if (fType.geographic && fType.published) {
                    gclayers.addOperationalLayerg2c(l);
                  }
                  //gclayers.addOperationalLayer(l);
                }
                ind++;
                //gclayers.addOperationalLayer(l);
                //$scope.map.addLayer(l);
              }
            });
          }
        }

        function getMainMapConfig(res, b) {
          if (!res.data === '') {
            scope.propmap = res.data;
            if (!angular.isUndefined(scope.propmap.extent)) {
              scope.go(scope.propmap.extent);
              if (angular.isDefined(scope.propmap.zoom))
                scope.map.getView().setZoom(scope.propmap.zoom);
            }
            if (!angular.isUndefined(scope.propmap.bcklayer)) {
              scope.baselayers;

              if (
                scope.propmap &&
                scope.propmap.bcklayer &&
                scope.propmap.bcklayer.length > 0
              )
                scope.propmap.bcklayer = [
                  scope.propmap.bcklayer[scope.propmap.bcklayer.length - 1],
                ];

              if (BaseMapFactory.resources.basemaps.length === 0) {
                BaseMapFactory.get().then((res) => {
                  scope.baselayers = BaseMapFactory.resources.basemaps;
                  scope.propmap.bcklayer.forEach((ft) => {
                    scope.baselayers.forEach((bl) => {
                      if (ft.label === bl.name) {
                        gclayers.addBackGroundLayerByDesc(bl);
                      }
                    });
                  });
                });
              } else {
                scope.baselayers = BaseMapFactory.resources.basemaps;
                scope.propmap.bcklayer.forEach((ft) => {
                  scope.baselayers.forEach((bl) => {
                    if (ft.label === bl.name) {
                      gclayers.addBackGroundLayerByDesc(bl);
                    }
                  });
                });
              }
            }
          }
        }

        scope.initMap = () => {
          // reset all layers
          gclayers.clearOperationalLayer();
          gclayers.clearOperationalLayerg2c();

          scope.map = new ol.Map({
            layers: [],
            target: 'map_branchement',
            view: new ol.View({ center: [0, 0], zoom: 2 }),
          });
          $timeout(() => {
            BaseMapFactory.get().then((res) => {
              if (BaseMapFactory.resources.basemaps.length) {
                gclayers.resetBackgroundLayer();
                // add OSM as initial and unique baselayer
                const osm = BaseMapFactory.resources.basemaps.find(x => x.type == 'OSM');
                const baseLayers = [];
                if (osm) {
                  osm.active = true;
                  gclayers.addBackGroundLayerByDesc(osm);
                  baseLayers.push(osm);
                  scope.baselayers = baseLayers;
                } else {
                  gclayers.addBackGroundLayerByDesc(
                    BaseMapFactory.resources.basemaps[0]
                  );
                }
              }
            });

            let ind = 0;
            FeatureTypeFactory.resources.featuretypes.forEach((fType) => {
              if (fType.storeName === BacAppFactory.appCfg.main.datastore) {
                for (let key in BacAppFactory.appCfg.main.extra
                  .branchementsCfg) {
                  if (
                    BacAppFactory.appCfg.main.extra.branchementsCfg[key] ===
                      fType.uid &&
                    fType.geographic &&
                    fType.published
                  ) {
                    const l = gcWMS.getOlLayerFromFeaturetypeInfo(fType, ind);
                    l.visible = true;
                    l.selected = true;
                    ind++;

                    // si dossier, ajouter représentation (no easy way)
                    if (
                      l.fti.uid ===
                      BacAppFactory.appCfg.main.extra.branchementsCfg
                        .branchement
                    ) {
                    }

                    if (
                      angular.isDefined(
                        BacAppFactory.appCfg.main.properties.selected_map_app
                      )
                    ) {
                      scope.selectedMap =
                        BacAppFactory.appCfg.main.properties.selected_map_app;

                      // type,name,appname
                      ConfigFactory.get(scope.selectedMap.name, 'map').then(
                        (res) => {
                          getMainMapConfig(res);

                          ParametersFactory.getbytype(
                            'MAP_MODELS_LAST_EDITED' + $rootScope.xgos.user.uid,
                            scope.selectedMap.name
                          ).then((res) => {
                            if (res.data.length > 0) {
                              let model = res.data[0].data;
                              getMainMapModel(model);
                              $rootScope.$broadcast('gcOperationalLayerOnInit');
                            }
                          });
                        }
                      );
                    }

                    gclayers.addOperationalLayerg2c(l);
                  }
                }
              }
            });

            // ajout des couches supplementaires

            // fit box

            scope.map.getView().fit(scope.dossierBbox, scope.map.getSize());

            if (
              scope.currentReport &&
              scope.currentReport.geometry &&
              scope.currentReport.geometry.coordinates
            ) {
              if (scope.currentReport.geometry.coordinates.length) {
                if (scope.currentReport.geometry.type === 'MultiPoint') {
                  scope.map
                    .getView()
                    .setCenter(scope.currentReport.geometry.coordinates[0]);
                } else {
                  scope.map
                    .getView()
                    .setCenter(scope.currentReport.geometry.coordinates);
                }
                scope.map.getView().setZoom(18);
              }
            }

            // dem broadcasts
            $rootScope.$broadcast('openTools_bizeditwidget', {
              forceConfig: {
                cfg: {
                  theme: 'kis_bac_branchement',
                  viseur: 0,
                  isGuide: 0,
                  isGuideOrth: 0,
                  isGuideFly: 0,
                },
              },
            });

            scope.featuresConfig =
              BacAppFactory.appCfg.main.mapConfiguration.featuresConfig;
            scope.AppAndroid = window.AppAndroid;
          });
        };

        /**
         * applyBranchementsFilter
         */
        scope.applyBranchementsFilter = () => {
          gclayers.getOperationalLayerg2cCollection().forEach((l) => {
            if (l.fti.theme === 'kis_bac_branchement') {
              const objz = [];
              scope.branchementsDossier.features.forEach((f) => {
                if (f.properties.object_uid === l.fti.uid) {
                  objz.push("'" + f.properties.object_id + "'");
                }
              });

              if (scope.showAllBranchemnents && scope.showAllBranchemnents.v) {
                l.cql_filter = objz.length
                  ? 'IN (' + objz.join(',') + ')'
                  : '1=2';
              } else {
                // l.cql_filter = objz.length ? "NOT IN (" + objz.join(',') + ")" : "1=1";
                l.cql_filter = '1=1';
              }
            }
          });

          $rootScope.$broadcast('gcOperationalLayerChange', '', 'applyall');
        };

        scope.$on('bizedit_endsave', (event, args) => {
          require('toastr').success('Branchement mis à jour', 'Branchement', {
            positionClass: 'toast-bottom-left',
          });

          for (let uid in args.records) {
            // add
            if (args.records[uid].adds.features.length) {
              const featuresToAdd = [];
              args.records[uid].adds.features.forEach((f) => {
                featuresToAdd.push({
                  type: 'Feature',
                  properties: {
                    id_dossier: scope.currentReport.id,
                    object_uid: uid,
                    object_id: f.id,
                  },
                });
              });

              const toAddToDossier = {
                type: 'FeatureCollection',
                features: featuresToAdd,
              };

              gaDomUtils.showGlobalLoader();
              BacAppFactory.addobjetbranchementtodossier(toAddToDossier).then(
                (res) => {
                  gaDomUtils.hideGlobalLoader();
                }
              );
            }
          }

          $timeout(() => {
            getBranchementsData().then((res) => {
              scope.applyBranchementsFilter();
            });
          }, 1000);
        });

        /**
         * new Demande Urbanisme
         * @type {{date_saisie: *}}
         */
        scope.newDemandeUrbanisme = {
          date_saisie: $filter('date')(new Date(), 'yyyy-MM-ddTHH:mm:ss.sssZ'),
        };

        scope.newUrbanismeAgentPicker = { value: false };
        scope.$watch(
          'newUrbanismeAgentPicker.value',
          (nap) => {
            if (
              nap &&
              angular.isDefined(nap) &&
              angular.isDefined(scope.newDemandeUrbanisme)
            ) {
              scope.newDemandeUrbanisme.agent = nap.login;
              scope.newDemandeUrbanisme.agent_name =
                nap.name + ' ' + nap.vorname;
            }
          },
          1
        );

        userslist = [];
        UsersFactory.getactiveusers().then((res) => {
          userslist = res.data;
        });

        let setDefaultUrbanismeAgent = () => {
          scope.newDemandeUrbanisme.agent = '';
          scope.newDemandeUrbanisme.agent_name = '';
          if (
            scope.currentDemandeUrbanismes &&
            scope.currentDemandeUrbanismes.length
          ) {
            scope.currentDemandeUrbanismes.forEach((v) => {
              if (
                scope.newDemandeUrbanisme &&
                (!scope.newDemandeUrbanisme.agent ||
                  scope.newDemandeUrbanisme.agent === '')
              ) {
                userslist.forEach((user) => {
                  if (user.login === v.properties.agent) {
                    scope.newDemandeUrbanisme.agent = v.properties.agent;
                    scope.newDemandeUrbanisme.agent_name =
                      user.name + ' ' + user.vorname;
                  }
                });
              }
            });
          }
          if (
            scope.newDemandeUrbanisme.agent === '' &&
            $rootScope.xgos.user.login !== 'root'
          ) {
            scope.newDemandeUrbanisme.agent = $rootScope.xgos.user.login;
            scope.newDemandeUrbanisme.agent_name =
              $rootScope.xgos.user.name + ' ' + $rootScope.xgos.user.vorname;
          }
        };

        /**
         * add Demande Urbanisme To Dossier
         */
        scope.addDemandeUrbanismeToDossier = () => {
          const feature = angular.copy(scope.newDemandeUrbanisme);
          delete feature.agent_name;
          feature.ref_dossier_bac = scope.currentReport.id;
          feature.etat = 'en cours';
          const pdata = {
            type: 'FeatureCollection',
            features: [
              {
                type: 'Feature',
                properties: feature,
              },
            ],
          };
          gaDomUtils.showGlobalLoader();
          BacAppFactory.adddemandeurbanisme(pdata, scope.currentReport.id).then(
            (res) => {
              setDossierArborescence();
              scope.newUrbanismeAgentPicker = { value: false };
              scope.newDemandeUrbanisme = {
                date_saisie: $filter('date')(
                  new Date(),
                  'yyyy-MM-ddTHH:mm:ss.sssZ'
                ),
              };
              require('toastr').success("Demande d'urbanisme ajoutée.", '', {
                positionClass: 'toast-bottom-left',
              });
              gaDomUtils.hideGlobalLoader();
            },
            () => {
              gaDomUtils.hideGlobalLoader();
            }
          );
        };

        scope.currentDemandeUrbanismes = [];
        scope.currentDemandeUrbanismesCopy = [];
        scope.typesDemandesUrbanismes =
          BacAppFactory.appCfg.main.demandeUrbanismeCfg;

        /**
         * set the whole report arborescence
         */
        let demandeUrbanismeBranchIndex;
        let ctrlBranchIndex;
        let setDossierArborescence = (controleId, doNotResetCtrl) => {
          scope.listCtrlFiliereDocumentsLies = {
            controles: [],
          };

          scope.reportTree.forEach((b, i) => {
            if (b.label === "Demandes d'urbanisme")
              demandeUrbanismeBranchIndex = i;
            if (b.label === 'Instructions') ctrlBranchIndex = i;
          });
          if (typeof AppAndroid == 'undefined') {
            scope.reportTree[demandeUrbanismeBranchIndex].children = [];
          }
          if (!doNotResetCtrl) {
            scope.reportTree[ctrlBranchIndex].children = [];
          }

          if (!scope.currentReport.id) {
            return;
          }

          // get demandes urbanisme
          console.log(scope.currentReport.id);

          BacAppFactory.getdemandeurbanisme(scope.currentReport.id).then(
            (res) => {
              console.log(res);

              scope.currentDemandeUrbanismes = gaJsUtils.sortByFeatureId(
                res.data.features,
                'desc'
              );
              scope.currentDemandeUrbanismesCopy = angular.copy(
                scope.currentDemandeUrbanismes
              );
              setDefaultUrbanismeAgent();
              scope.currentDemandeUrbanismes.forEach((c, idx) => {
                let label;
                scope.typesDemandesUrbanismes.forEach((v) => {
                  if (c.properties.type === v.type) {
                    label =
                      v.label +
                      ' ' +
                      $filter('date')(c.properties.date_saisie, 'dd.MM.yyyy');
                  }
                });

                //  var ctrlLabel =AncAppFactory.getControleName(c.properties.type, c.properties.date_saisie);
                const ctrlBranch = {
                  label: label,
                  template:
                    'js/XG/widgets/bacapp/main/views/modals/modal.report.urbanisme.html',
                  demandeUrbanismeId: c.id,
                  classes: [],
                };

                // set in tree
                scope.reportTree[demandeUrbanismeBranchIndex].children.push(
                  ctrlBranch
                );
                scope.reportTreeControl.expand_branch(
                  scope.reportTree[demandeUrbanismeBranchIndex]
                );
              });
            }
          );

          refreshListeControles(controleId);
        };

        /**
         * Recuperation de l'url du formulaire de controle
         */
        scope.getFormulaireUrbanismeURL = () => {
          let file;
          scope.typesDemandesUrbanismes.forEach((x) => {
            if (scope.currentDemandeUrbanisme.properties) {
              if (x.type === scope.currentDemandeUrbanisme.properties.type)
                file = x.template;
            }
          });
          return 'js/XG/widgets/bacapp/main/views/urbanisme/' + file;
        };

        /**
         * remove Demande Urbanisme From Dossier
         * @param v
         */
        scope.removeDemandeUrbanismeFromDossier = (v) => {
          const ans = confirm(
            "êtes-vous sur de vouloir supprimer cette demande d'urbanisme ?"
          );
          if (ans) {
            BacAppFactory.removedemandeurbanisme(
              v.id,
              scope.currentReport.id,
              v.properties.type
            ).then((res) => {
              setDossierArborescence();
              require('toastr').success("Demande d'urbanisme supprimée.", '', {
                positionClass: 'toast-bottom-left',
              });
            });
          }
        };

        /**
         * caracteristiques des constructions
         * @type {Array}
         */
        scope.caracteristiquesdesconstructions = [];
        scope.add_caracteristiques = function (type) {
          scope.caracteristiquesdesconstructions.push({
            type: type,
          });
        };

        /**
         * remove caracteristique
         * @param index
         */
        scope.remove_caracteristique = (index) => {
          scope.caracteristiquesdesconstructions.splice(index, 1);
        };

        /**
         * render Demande Urbanisme Type
         * @param type
         * @returns {*}
         */
        scope.renderDemandeUrbanismeType = (type) => {
          const res = type;
          scope.typesDemandesUrbanismes.forEach((v) => {
            if (v.type === type) {
              res = v.label;
            }
          });
          return res;
        };

        /**
         * update demande urbanisme
         */
        scope.update_demande_urbanisme = () => {
          console.log(scope.caracteristiquesdesconstructions);
          let data = '';
          if (scope.caracteristiquesdesconstructions.length) {
            const feature_caracteristique = [];
            scope.caracteristiquesdesconstructions.forEach((o) => {
              o.id_demande_urbanisme = scope.currentDemandeUrbanisme.id;
              feature_caracteristique.push({
                type: 'Feature',
                properties: o,
              });
            });
            data = {
              type: 'FeatureCollection',
              features: feature_caracteristique,
            };
          }

          BacAppFactory.addcaracteristiqueconstruction(
            data,
            scope.currentDemandeUrbanisme.id,
            scope.currentReport.id
          ).then(
            (res) => {},
            () => {}
          );

          const feature = angular.copy(scope.currentDemandeUrbanisme);
          const pdata = {
            type: 'FeatureCollection',
            features: [
              {
                type: 'Feature',
                properties: feature,
              },
            ],
          };

          gaDomUtils.showGlobalLoader();
          BacAppFactory.updatedemandeurbanisme(
            pdata,
            scope.currentReport.id
          ).then(
            (res) => {
              console.log(res.data);
              gaDomUtils.hideGlobalLoader();
              require('toastr').success('Informations enregistrées.', '', {
                positionClass: 'toast-bottom-left',
              });
            },
            () => {
              gaDomUtils.hideGlobalLoader();
            }
          );
        };

        $rootScope.$on('pushDDCInfoToControle', (event, data) => {
          if (data) {
            Object.keys(data).forEach((prop) => {
              switch (prop) {
                case 'date_decision':
                  scope.cdata.ddc.date_decision = data[prop];
                  break;
                case 'demandeur':
                  scope.cdata.info_generales.demandeur = data[prop];
                  break;
                case 'date_demande':
                  scope.cdata.datesDossier.date_demande = data[prop];
                  break;
                case 'nature_decision':
                  scope.cdata.ddc.nature_decision = data[prop];
                  break;
                case 'representant':
                  if (
                    !gaJsUtils.checkNestedProperty(
                      'info_generales.representant',
                      scope.cdata
                    )
                  ) {
                    gaJsUtils.setNestedProperty(
                      'info_generales.representant',
                      scope.cdata,
                      null
                    );
                  }
                  scope.cdata.info_generales.representant = data[prop];
                  break;
                case 'nature_travaux':
                  if (
                    !gaJsUtils.checkNestedProperty(
                      'info_generales.nature_travaux',
                      scope.cdata
                    )
                  ) {
                    gaJsUtils.setNestedProperty(
                      'info_generales.nature_travaux',
                      scope.cdata,
                      null
                    );
                  }
                  scope.cdata.info_generales.nature_travaux.objet = data[prop];
                  scope.cdata.ddc.nature_travaux = data[prop];
                  break;
                case 'surface_plancher':
                  scope.cdata.avis_tech.surface_plancher_ddc = data[prop];
                  break;
                case 'objet':
                  if (
                    !gaJsUtils.checkNestedProperty(
                      'info_generales.demande.objet',
                      scope.cdata
                    )
                  ) {
                    gaJsUtils.setNestedProperty(
                      'info_generales.demande.objet',
                      scope.cdata,
                      null
                    );
                  }
                  scope.cdata.info_generales.demande.objet = data[prop];

                  break;
                case 'destination':
                  if (
                    !gaJsUtils.checkNestedProperty(
                      'info_generales.destination',
                      scope.cdata
                    )
                  ) {
                    gaJsUtils.setNestedProperty(
                      'info_generales.destination',
                      scope.cdata,
                      null
                    );
                  }
                  scope.cdata.info_generales.destination = data[prop];
                  break;
                case 'date_ouverture_chantier':
                  scope.cdata.ddc.date_ouverture_chantier = data[prop];
                  break;
                case 'surface_terrain':
                  if (
                    !gaJsUtils.checkNestedProperty(
                      'info_generales.parcelleHabitation.superficie',
                      scope.cdata
                    )
                  ) {
                    gaJsUtils.setNestedProperty(
                      'info_generales.parcelleHabitation.superficie',
                      scope.cdata,
                      null
                    );
                  }
                  scope.cdata.info_generales.parcelleHabitation.superficie =
                    data[prop];
                  break;
                case 'date_achevement_travaux':
                  scope.cdata.ddc.date_daact = data[prop];
                  break;
              }
            });

            require('toastr').success('Données DDC récupérée.');
          }
        });

        scope.$on('addDDCDossierToControle', (event, data) => {
          if (!data.reInit) {
            angular.isUndefined(scope.cdata.dossiersDDC);
            scope.cdata.dossiersDDC = [];

            data.forEach((id) => {
              scope.cdata.dossiersDDC.push(id);
            });
          } else {
            delete scope.cdata.dossiersDDC;
          }
          scope.saveControleDetail();
        });

        scope.openDDC = (id) => {
          $rootScope.$broadcast('openDDCDossier', id);
        };

        /* -- affichage des infos relatives à la facturation ? --*/
        scope.displayFacturationControle =
          gaJsUtils.checkNestedProperty(
            'appCfg.main.properties.dolibarr.active',
            BacAppFactory
          ) === true;
        scope.getUrlFactureDolibarr = (id) => {
          return {
            url:
              BacAppFactory.appCfg.main.properties.dolibarr.url +
              'compta/facture/card.php?facid=' +
              id,
            pdf:
              BacAppFactory.appCfg.main.properties.dolibarr.url +
              'compta/facture/card.php?facid=' +
              id,
          };
        };

        scope.saveElementsFeatures = () => {
          scope.map.once('postcompose', (event) => {
            const canvas = event.context.canvas;
            let context = canvas.getContext('2d');

            // draw behind existing image
            context.globalCompositeOperation = 'destination-over';
            // add background
            context.fillStyle = 'white';
            context.fillRect(0, 0, canvas.width, canvas.height);
            // reset the context
            context.globalCompositeOperation = 'source-over';

            const image = canvas.toDataURL('image/png');

            BacAppFactory.base64topng(image, scope.currentReport.id).then(
              () => {
                require('toastr').success(
                  'Représentation enregistrée dans les documents liés.',
                  '',
                  {
                    positionClass: 'toast-bottom-left',
                  }
                );
              }
            );
          });

          scope.map.renderSync();
        };

        let alerteDialog;
        scope.$on('edit_alerte_dossier', (event, data) => {
          if (data) {
            BacAppFactory.getdossier(data).then((res) => {
              if (res.data.features.length) {
                scope.currentReport = res.data.features[0];
                dateUtils.convertAllDatesToDateString(
                  scope.currentReport.properties,
                  dossierDateNames
                );
                alerteDialog = ngDialog.open({
                  template:
                    'js/XG/widgets/bacapp/main/views/modals/modal.alerte.edit.html',
                  className:
                    'ngdialog-theme-plain width800 nopadding miniclose',
                  closeByDocument: false,
                  scope: scope,
                  preCloseCallback: () => {
                    scope.currentReport = {};
                  },
                });
              }
            });
          }
        });

        scope.updateAlerte = (update) => {
          if (angular.isDefined(scope.currentReport)) {
            let ans = null;
            if (!update) {
              ans = confirm(
                'Etes-vous sur de vouloir supprimer cette alerte ?'
              );
              if (ans) {
                scope.currentReport.properties.alerte = '';
                scope.currentReport.properties.alerte_echeance = null;
              }
            }
            if (ans == null || ans) scope.saveReport();
          }
          alerteDialog.close();
        };

        scope.openAttachmentsDialog = (obj) => {
          dateUtils.convertAllDatesToDateString(
            obj.properties,
            dossierDateNames
          );
          scope.currentReport = obj;
          let dossierAttachmentInfo = ancBacTools.getCurrentDossierAttachmentsInfos(
            scope.doss,
            scope.currentReport
          );

          scope.dossierAttachmentData = {
            id: obj.id,
            featuretype: 'kis_bac_dossier',
            attachmentsNo:
              dossierAttachmentInfo !== null
                ? dossierAttachmentInfo.dossierAttachmentsNo
                : 0,
          };

          scope.documentsCheckedForMail = [];
          scope.listCtrlFiliereDocumentsLies = { controles: [] };
          prepareControles();

          ngDialog.open({
            template:
              'js/XG/widgets/ancapp/main/views/modals/modal.report.dossier.attachments.html',
            className:
              'ngdialog-theme-plain width1200 height700 nopadding miniclose',
            closeByDocument: false,
            scope: scope,
            preCloseCallback: () => {
              scope.currentReport = {};
            },
          });

          function prepareControles() {
            BacAppFactory.getcontroles(scope.currentReport.id).then((res) => {
              scope.currentControles = gaJsUtils.sortByFeatureId(
                res.data.features,
                'desc'
              );
              scope.currentCtrlShowFiles = undefined;
              scope.currentControles.forEach((c, idx) => {
                let ctrlLabel = BacAppFactory.getControleName(
                  c.properties.type,
                  c.properties.date_passage
                );
                c.attachmentsNo = getControleAttachmentNo(
                  scope.doss,
                  scope.currentReport,
                  c.id
                );
                const toPushControle = {
                  label:
                    ctrlLabel +
                    (c.properties.etat === 'ouvert'
                      ? ' (instruction en cours)'
                      : ''),
                  attachmentData: {
                    id: c.id,
                    featuretype: 'kis_bac_dossier_controle',
                    feature: c,
                  },
                };
                scope.listCtrlFiliereDocumentsLies.controles.push(
                  toPushControle
                );
                if (
                  c.properties.etat === 'ouvert' &&
                  angular.isUndefined(scope.currentCtrlShowFiles)
                ) {
                  scope.currentCtrlShowFiles = toPushControle;
                }
              });
              scope.fillDossierAttachmentsTab();
            });
          }
        };

        scope.dossierSpecialActions = [
          {
            class: 'btn btn-default btn-xs',
            icone: 'fa fa-paperclip ancBacDossierListAttachmentsButton',
            text: 'Documents du dossier',
            buttonLabel:
              "' (' + obj.properties.attachmentsInfos.totalAttachmentsNo + ')'",
            buttonLabelIsExpression: true,
            callFunction: scope.openAttachmentsDialog,
          },
        ];

        scope.$watch(
          'currentControles',
          (newValue) => {
            if (angular.isDefined(scope.currentControles)) {
              scope.updateDocumentsLabel(
                scope.currentControles,
                'instructions',
                'controleId',
                'documents_controle',
                'Documents liés'
              );
              ancBacTools.recalculateDocumentsNoforTab(
                scope.doss,
                scope.currentReport,
                scope.documentLiesTousTabs,
                scope.currentControles,
                'controles',
                'Contrôles',
                'controlesAttachments'
              );
              scope.recalculateDocumentsNo();
            }
          },
          true
        );

        scope.$watch(
          'dossierAttachmentData',
          () => {
            const currentDossierAttachmentsInfos = ancBacTools.getCurrentDossierAttachmentsInfos(
              scope.doss,
              scope.currentReport
            );
            if (
              angular.isDefined(scope.dossierAttachmentData) &&
              currentDossierAttachmentsInfos !== null
            ) {
              currentDossierAttachmentsInfos.dossierAttachmentsNo =
                scope.dossierAttachmentData.attachmentsNo;
              ancBacTools.updateTabLabel(
                scope.documentLiesTousTabs,
                'dossier',
                'Dossier',
                scope.dossierAttachmentData.attachmentsNo
              );
              scope.recalculateDocumentsNo();
            }
          },
          true
        );

        scope.updateDocumentsLabel = (
          sourceElements,
          mainIdentifier,
          idName,
          documentsIdentifier,
          documentsLabel
        ) => {
          if (angular.isDefined(sourceElements)) {
            let mainElement = scope.reportTree.find((element) => {
              return element.key === mainIdentifier;
            });
            if (angular.isDefined(mainElement)) {
              sourceElements.forEach((item) => {
                if (angular.isDefined(mainElement.children)) {
                  let childElement = mainElement.children.find((element) => {
                    return element[idName] === item.id;
                  });
                  if (angular.isDefined(childElement)) {
                    let documentsElement = childElement.children[0];
                    if (angular.isDefined(documentsElement)) {
                      if (angular.isUndefined(item.attachmentsNo)) {
                        item.attachmentsNo = getControleAttachmentNo(
                          scope.doss,
                          scope.currentReport,
                          item.id
                        );
                      }
                      documentsElement.label =
                        documentsLabel + ' (' + item.attachmentsNo + ')';
                    }
                  }
                }
              });
            }
          }
        };

        scope.updateAllTabsLabels = () => {
          if (angular.isDefined(scope.currentControles)) {
            ancBacTools.recalculateDocumentsNoforTab(
              scope.doss,
              scope.currentReport,
              scope.documentLiesTousTabs,
              scope.currentControles,
              'controles',
              'Contrôles',
              'controlesAttachments'
            );
          }
          scope.recalculateDocumentsNo();
        };

        scope.recalculateDocumentsNo = () => {
          let currentDossierAttachmentsInfos = ancBacTools.getCurrentDossierAttachmentsInfos(
            scope.doss,
            scope.currentReport
          );
          if (currentDossierAttachmentsInfos !== null) {
            currentDossierAttachmentsInfos.totalAttachmentsNo = 0;
            addValue(currentDossierAttachmentsInfos.controlesAttachmentsNo);
            addValue(currentDossierAttachmentsInfos.dossierAttachmentsNo);
            let documentsElement = scope.reportTree.find(function (element) {
              return element.key === 'documents_dossier';
            });
            if (angular.isDefined(documentsElement)) {
              documentsElement.label =
                'Documents du dossier (' +
                currentDossierAttachmentsInfos.totalAttachmentsNo +
                ')';
            }

            function addValue(value) {
              if (angular.isDefined(value) && !isNaN(value)) {
                currentDossierAttachmentsInfos.totalAttachmentsNo += value;
              }
            }
          }
        };

        scope.checkboxChanged = (featureId, document, isChecked) => {
          ancBacTools.checkboxChanged(
            scope.documentsCheckedForMail,
            featureId,
            document,
            isChecked
          );
        };

        scope.getSelectedCheckboxes = (featureId) => {
          let documentsForFeature = scope.documentsCheckedForMail.filter(
            (element) => element.featureId === featureId
          );
          return documentsForFeature.map((element) => element.document);
        };

        scope.prepareDocumentsForMail = () => {
          const featureTypeInfos = [];
          featureTypeInfos.push({
            featureType: 'kis_bac_dossier',
            folder: 'Dossier',
            hasSubfolders: false,
          });
          featureTypeInfos.push({
            featureType: 'kis_bac_dossier_controle',
            folder: 'Instructions',
            features: scope.listCtrlFiliereDocumentsLies.controles,
            hasSubfolders: true,
          });
          const documentsInfos = {
            documentsCheckedForMail: scope.documentsCheckedForMail,
            featureTypeInfos: featureTypeInfos,
          };
          ancBacTools.prepareDocumentsForMail(documentsInfos);
        };

        scope.importFromArchive = () => {
          if ($location.search().app) {
            localStorage.setItem('app', $location.search().app);
          }
          ngDialog.open({
            template:
              'js/XG/widgets/bacapp/main/views/modals/modal.importFromArchive.html',
            className: 'ngdialog-theme-plain',
            closeByDocument: false,
            scope: scope,
          });
        };

        scope.initDropzone = function () {
          this.on('success', function (file, response) {
            ngDialog.close();
            if (response.success) {
              window.open(
                '/services/' +
                  response.portalId +
                  '/documents/downloaddocx?' +
                  '&name=' +
                  response.reportPath.replace('\\', '/')
              );
            } else {
              require('toastr').error(
                "Une erreur s'est produite pendant le traitement de l'archive :<br/>" +
                  response.errorMessage
              );
            }
            scope.refreshReports();
          });
        };

        scope.action = { selectedAction: 'map' };

        scope.executeAction = () => {
          if (scope.action.selectedAction === 'rdv' && scope.priseRDV.active) {
            scope.actionPriseRdv();
          }
          if (scope.action.selectedAction === 'map') {
            openMapFilter();
          }
          if (scope.action.selectedAction === 'change_status') {
            scope.changeStatutDossiersEnMasse();
          }
        };

        function openMapFilter() {
          scope.ftidoss = scope.dossierFti;
          ngDialog.open({
            template: 'js/XG/widgets/ancapp/main/views/map_filter.html',
            className: 'ngdialog-theme-plain height700 nopadding',
            closeByDocument: false,
            showClose: true,
            scope: scope,
          });
        }

        scope.changeFileFilterButton = (newValue)=>{
          scope.dossierFilterBtn.v = scope.dossierFilterBtn.v !== newValue
            ? newValue
            : scope.dossierFilterBtn.v;
          filesToUpdateData.length = 0;
          scope.res.length = 0;
        };
      },
    };
  };

  listeDossiersBac.$inject = [
    'BacAppFactory',
    'FeatureTypeFactory',
    '$filter',
    '$rootScope',
    'ngDialog',
    'gaDomUtils',
    'FeatureHistoryFactory',
    '$timeout',
    'QueryFactory',
    'EditFactory',
    '$sce',
    'DocumentFactory',
    '$q',
    'CalendarFactory',
    'gaJsUtils',
    'UsersFactory',
    '$location',
    'FeatureAttachmentFactory',
    'gclayers',
    'gcWMS',
    'panelsManager',
    'BaseMapFactory',
    'ConfigFactory',
    'kisCalendarFactory',
    'ancBacTools',
    'uiCalendarConfig',
    'dateUtils',
    'HtmlUtils',
    'ParametersFactory'
  ];
  return listeDossiersBac;
});
