Commit 9ba8f8f1 authored by Stephane Bouvry's avatar Stephane Bouvry
Browse files

Exportation des activités (à améliorer)

parent 7bbf4fc3
Loading
Loading
Loading
Loading
Loading
+11 −10
Original line number Diff line number Diff line
@@ -1218,7 +1218,6 @@ class ProjectGrantController extends AbstractOscarController implements UseNotif
        $format = $this->params()->fromPost('format', 'csv');

        $delimiter = "\t";

        // Récupération des IDS
        if ($request->isPost()) {
            $paramID = $this->params()->fromPost('ids', '');
@@ -1228,7 +1227,6 @@ class ProjectGrantController extends AbstractOscarController implements UseNotif
        } else {
            return $this->getResponseUnauthorized();
        };

        $datas = new ExportDatas($this->getProjectGrantService(), $this->getOscarUserContextService());
        $dt = $datas->output($paramID, $fields, $perimeter);

@@ -2798,6 +2796,7 @@ class ProjectGrantController extends AbstractOscarController implements UseNotif
            'titleActivity' => $this->oscarText('Activités dans mes structures'),
            'titleProject' => $this->oscarText('Projets dans mes structures'),
            'perimeter' => 'org',
            'exportable' => true,
            'perimeterOptions' => $perimeterOptions,
            'perimeterDetails' => $perimeterDetails,
            'perimeterExclude' => $perimeterExclude,
@@ -2811,7 +2810,8 @@ class ProjectGrantController extends AbstractOscarController implements UseNotif
        return $this->advancedSearch2Action('global', [
            'titleActivity' => $this->oscarText('Activités'),
            'titleProject' => $this->oscarText('Projets'),
            'perimeter' => 'global'
            'perimeter' => 'global',
            'exportable' => true
        ]);
    }

@@ -2866,9 +2866,6 @@ class ProjectGrantController extends AbstractOscarController implements UseNotif
                        ->getIdsWithOrganizations($include);
                }




                break;

            default:
@@ -2906,9 +2903,11 @@ class ProjectGrantController extends AbstractOscarController implements UseNotif
                'filters' => $this->params()->fromQuery('f', []),
                'project' => $projectMode,
                'restricted_ids' => $restricted_ids,
                'exportable' => $viewOptions['exportable'] === true,
            ];

            $response = new JsonModel($this->getProjectGrantService()->search2($params));
            $datas = $this->getProjectGrantService()->search2($params);
            $response = new JsonModel($datas);
            return $response;
        }

@@ -2939,6 +2938,8 @@ class ProjectGrantController extends AbstractOscarController implements UseNotif
        $filtersOptions['directions'] = $directions;
        $filtersOptions['numbers'] = $this->getProjectGrantSearchService()->getFilterOptionsActivityNumbers();

        $filtersOptions['fields'] = $this->getProjectGrantSearchService()->getFilterOptionsFieldCSV();

        //'activityDocumentTypes' => $this->getProjectGrantSearchService()->getFilterOptionsMilestones(),
        //'countries' => $this->getProjectGrantSearchService()->getFilterOptionsCountries(),

+37 −39
Original line number Diff line number Diff line
@@ -2275,30 +2275,14 @@ class ProjectGrantService implements UseGearmanJobLauncherService, UseOscarConfi
            ]
        ];

        $EXPORT_LIMIT = 5000;

        $modeProject = $params['project'] == 1;

        if( $params['restricted_ids'] !== false ){
            $body['query']['bool']['filter'][] = [
                'terms' => [ 'id' => array_values($params['restricted_ids'])]
            ];
//            if( $modeProject ){
//                $body['query']['bool']['filter'][] = [
//                    "nested" => [
//                        "path" => "activities",
//                        "query" => [
//                            "bool" => [
//                                "filter" => [
//                                    ["terms" => ["activities.id" => array_values($params['restricted_ids'])]]
//                                ]
//                            ]
//                        ]
//                    ]
//                ];
//            } else {
//                $body['query']['bool']['filter'][] = [
//                    'terms' => [ 'id' => array_values($params['restricted_ids'])]
//                ];
//            }
        }

        $filters = [];
@@ -2758,12 +2742,13 @@ class ProjectGrantService implements UseGearmanJobLauncherService, UseOscarConfi

        try {
            if ($params['project'] == '1') {
                $key = 'projects';
                $result = $this->getSearchEngineProjectStrategy()->searchRaw($params['q'], $limit = 1000, $body);
            } else {
                $key = 'activities';
                $result = $this->getSearchEngineStrategy()->searchRaw($params['q'], $limit = 1000, $body);
            }

            if ($params['project'] == 1) {
            $total = $result['hits']['total']['value'];
            $pages = ceil($total / $size);
            $datas = [];
@@ -2773,22 +2758,35 @@ class ProjectGrantService implements UseGearmanJobLauncherService, UseOscarConfi
                $dt['_score'] = $hit['_score'];
                $datas[] = $dt;
            }
            $out[$key] = $datas;

                $out["projects"] = $datas;
            } else {
                $total = $result['hits']['total']['value'];
                $pages = ceil($total / $size);
                $datas = [];

                foreach ($result['hits']['hits'] as $hit) {
                    $dt = $hit['_source'];
                    $dt['_score'] = $hit['_score'];
                    $datas[] = $dt;
            $total = $result['hits']['total']['value'];
            $ids_export_values = null;
            $ids_export_enable = false;
            $ids_export_warning = "Export indisponible";
            if( $params['exportable'] === true ){
                $ids_export_enable = true;
                if( $total < $EXPORT_LIMIT ){
                    $body['from'] = 0;
                    $body['size'] = $EXPORT_LIMIT;
                    $body['_source'] = false;
                    $resultIds = $this->getSearchEngineStrategy()->searchRaw($params['q'], $limit = $EXPORT_LIMIT, $body);
                    $ids_export_values = [];
                    foreach ($resultIds['hits']['hits'] as $result) {
                        $ids_export_values[] = $result['_id'];
                    }
                    $ids_export_warning = count($ids_export_values) ? "" : "Aucune données exportables";
                } else {
                    $ids_export_warning = "Trop de résultat pour l'exportation";
                }

                $out["activities"] = $datas;
            }

            $out['ids_export_warning'] = $ids_export_warning;
            $out['ids_export_enabled'] = $ids_export_enable;
            $out['ids_export_values'] = $ids_export_values;


        } catch (\Exception $e) {
            $out['error'] = $e->getMessage();
        }
+2 −1
Original line number Diff line number Diff line
<template>
    <form :action="urlPost" method="POST">
        <input type="hidden" name="ids" :value="ids" />
        <input type="hidden" :value="selectedFields" name="fields">
        <div class="btn-group">
            <select name="format" class="form-control xs">
                <option value="xls" selected>XLS (Excel)</option>
@@ -12,7 +13,7 @@
        <section v-show="showConfiguration" class="overlay">
            <div class="overlay-content">
                <h2>Champs à exporter</h2>
                <input type="hidden" :value="selectedFields" name="fields">

                <hr>

                <h3 @click="selectSection(fieldsUI.core)"><i class="icon-cube"></i>Champs de base</h3>
+0 −16
Original line number Diff line number Diff line
@@ -36,10 +36,6 @@ export default {
      const delta = 3;
      const range = [];
      let rangeWithDots = [];
      let l;

      console.log("-------------------------");
      console.log(current,"/",total);

      if( total <= delta*2+3 ){
        rangeWithDots = Array.from({length: total}, (_,i) => i+1);
@@ -47,19 +43,13 @@ export default {

        let start = current-delta;
        let end = current+delta;
        console.log("bornes départ", start,',',end);



        let decalage = 0;

        if( start < 1 ){
          decalage = Math.abs(start)+1;
          console.log("decalage début", decalage);
        }
        if( end > total ){
          decalage = -(end-total);
          console.log("decalage fin", decalage);
        }

        if(decalage != 0 ){
@@ -67,8 +57,6 @@ export default {
          end += decalage;
        }

        console.log("start", start, "end", end);

        for(let i = start; i <= end; ++i){
          range.push(i);
        }
@@ -85,10 +73,6 @@ export default {


      }

      console.log( rangeWithDots);


      return rangeWithDots;
    }
  },
+185 −1
Original line number Diff line number Diff line
@@ -9,6 +9,9 @@
      {{ filtersOptions.titleActivity }}
    </span>
  </h1>



  <form @submit.prevent="search()">
    <div class="input-group input-group-lg">
    <input type="search" class="form-control" placeholder="Rechercher..." v-model="searchText"/>
@@ -191,6 +194,94 @@
    {{ total }} résultat(s)
    <span v-if="pages > 1"> - page {{ page }} / {{ pages }}</span>
  </h2>
  <section v-if="ids_export_enabled" class="text-center">
    <i class="icon-database-1"></i>
    <span class="text-danger" v-if="ids_export_warning">
      {{ ids_export_warning }}
    </span>
    <div v-if="ids_export_values">
      <form action="/activites-de-recherche/csv" method="POST">
        <input type="hidden" name="ids" :value="ids_export_values.join(',')" />
        <input type="hidden" :value="selectedFields" name="fields">

        <select name="" id="" class="form-control">
          <option value="xls">XLS (Excel)</option>
          <option value="csv">CSV (Comma Separated Value)</option>
        </select>
        <div class="overlay" v-if="configureExport">
          <div class="overlay-content">
            <h3>Configuration des exportations</h3>

            <section>
              <h3 @click="selectSection(fieldsUI.core)"><i class="icon-cube"></i>Champs de base</h3>
              <div class="cols">
                <label v-for="field, i in fieldsUI.core" class="col3">
                  <input type="checkbox" :checked="field.selected" @click="toggleField(field.label)"/>
                  {{ field.label }}
                </label>
              </div>

              <h3 @click="selectSection(fieldsUI.organizations)"><i class="icon-building-filled"></i>Organisations</h3>
              <div class="cols">
                <label v-for="field, i in fieldsUI.organizations" class="col3">
                  <input type="checkbox" :checked="field.selected"  @click="toggleField(field.label)"/>
                  {{ field.label }}
                </label>
              </div>

              <h3 @click="selectSection(fieldsUI.persons)"><i class="icon-user"></i>Membres</h3>
              <div class="cols">
                <label v-for="field, i in fieldsUI.persons" class="col3">
                  <input type="checkbox" :checked="field.selected"  @click="toggleField(field.label)"/>
                  {{ field.label }}
                </label>
              </div>

              <h3 @click="selectSection(fieldsUI.milestones)"><i class="icon-calendar"></i>Jalons</h3>
              <div class="cols">
                <label v-for="field, i in fieldsUI.milestones" class="col3">
                  <input type="checkbox" :checked="field.selected"  @click="toggleField(field.label)"/>
                  {{ field.label }}
                </label>
              </div>
              <hr>
              <h3 @click="selectSection(fieldsUI.numerotation)"><i class="icon-calendar"></i>Numérotations</h3>
              <div class="cols">
                <label v-for="field, i in fieldsUI.numerotation" class="col3">
                  <input type="checkbox" :checked="field.selected"  @click="toggleField(field.label)"/>
                  {{ field.label }}
                </label>
              </div>

              <h3 @click="selectSection(fieldsUI.computed)"><i class="icon-calendar"></i>Champs calculés</h3>
              <div class="cols">
                <label v-for="field, i in fieldsUI.computed" class="col3">
                  <input type="checkbox" :checked="field.selected"  @click="toggleField(field.label)"/>
                  {{ field.label }}
                </label>
              </div>
              <hr>
              <nav>
                <a class="btn btn-default" @click="selectAll()">
                  <small v-if="switchSelect">Sélectionner tous les champs</small>
                  <small v-else>Déselectionner tous les champs</small>
                </a>
                <button class="btn btn-default" type="button" @click="configureExport = false">Fermer</button>
                <button class="btn btn-primary" type="submit" @click="configureExport = false">Exporter</button>
              </nav>
            </section>
          </div>
        </div>
        <button class="btn btn-primary" type="button" @click="handlerConfigureExport">
          <i class="icon-cog"></i>
          CONFIGURER
        </button>
        <button class="btn btn-primary" type="submit">
          EXPORTER les RESULTATS
        </button>
      </form>
    </div>
  </section>
  <nav v-if="pages > 1">
    <pagination :page="page" :pages="pages" @clickpage="handlerPage"/>
  </nav>
@@ -275,6 +366,22 @@ export default {
  computed: {
    excludeOrg(){
      return this.exclude.map( i=> parseInt(i));
    },
    fieldsUI(){
      let fieldsUi = [];
      for( var p in this.filtersOptions.fields ){
        if( this.filtersOptions.fields.hasOwnProperty(p) ){
          fieldsUi[p] = [];
          this.filtersOptions.fields[p].forEach((field) => {
            fieldsUi[p].push({
              label: field,
              selected: this.selectedFields.indexOf(field) > -1
            });
          })
        }
      }

      return fieldsUi;
    }
  },

@@ -292,6 +399,13 @@ export default {
      modeCompact: false,
      overCtrl: false,

      configureExport: false,
      selectedFields: [],

      ids_export_enabled: false,
      ids_export_values: null,
      ids_export_warning: "",

      // Résultats
      results: [],
      exclude: [],
@@ -305,6 +419,10 @@ export default {
  },

  methods:{
    handlerConfigureExport(){
      this.configureExport = true;
    },

    handlerReverseExclude(){
      let reverse = [];
      Object.keys(this.filtersOptions.perimeterDetails).forEach(item=>{
@@ -315,6 +433,7 @@ export default {
      this.exclude = reverse;
      this.search(1);
    },

    handlerExclude(organizationId){
      console.log('toogle', organizationId);
      if( this.exclude.indexOf(organizationId) > -1){
@@ -460,7 +579,10 @@ export default {
        this.total = ok.data.total;
        this.page = ok.data.page;
        this.pages = ok.data.pages;
        this.query = ok.data.query;
        this.pages = ok.data.pages;
        this.ids_export_enabled = ok.data.ids_export_enabled;
        this.ids_export_values = ok.data.ids_export_values;
        this.ids_export_warning = ok.data.ids_export_warning;
        this.filters = ok.data.filters;
        this.error = ok.data.error;
        if( this.modeProject ){
@@ -469,6 +591,68 @@ export default {
          this.results = ok.data.activities;
        }
      })
    },

    selectSection(group){
      let select = true;
      group.forEach(item => {
        if( item.selected === false ) select = false;
      });

      select = !select;
      if( select === false ){
        group.forEach(item => {
          if( this.selectedFields.indexOf(item.label) > -1 ){
            this.selectedFields.splice(this.selectedFields.indexOf(item.label), 1);
          }
        });
      } else {
        group.forEach(item => {
          if( this.selectedFields.indexOf(item.label) < 0 ){
            this.selectedFields.push(item.label);
          }
        });
      }
    },

    selectAll(){
      var selected = [];
      if( this.switchSelect === true ){
        for( var p in this.fields ){
          if( this.fields.hasOwnProperty(p) ){
            this.fields[p].forEach((field) => {
              selected.push(field);
            })
          }
        }

      }
      this.switchSelect = !this.switchSelect;
      this.selectedFields = selected;
    },

    toggleField(field){
      if( this.selectedFields.indexOf(field) > -1 ){
        this.selectedFields.splice(this.selectedFields.indexOf(field), 1);
      } else {
        this.selectedFields.push(field);
      }
    }
  },

  created(){
    if( window.localStorage && window.localStorage.getItem('export_fields') ){
      this.selectedFields = JSON.parse(window.localStorage.getItem('export_fields'));
    } else {
      this.selectedFields = [];
    }
  },

  watch: {
    selectedFields(newVal){
      if( window.localStorage ){
        window.localStorage.setItem('export_fields', JSON.stringify(this.selectedFields));
      }
    }
  },