commit
1e720f7587
21 changed files with 390 additions and 109 deletions
|
@ -40,6 +40,54 @@ class Champs::CarteController < ApplicationController
|
||||||
response.status = 503
|
response.status = 503
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def index
|
||||||
|
@selector = ".carte-#{params[:champ_id]}"
|
||||||
|
@champ = policy_scope(Champ).find(params[:champ_id])
|
||||||
|
@update_cadastres = params[:cadastres]
|
||||||
|
|
||||||
|
if @champ.cadastres? && @update_cadastres
|
||||||
|
@champ.geo_areas.cadastres.destroy_all
|
||||||
|
@champ.geo_areas += GeoArea.from_feature_collection(cadastres_features_collection(@champ.to_feature_collection))
|
||||||
|
@champ.save!
|
||||||
|
end
|
||||||
|
rescue ApiCarto::API::ResourceNotFound
|
||||||
|
flash.alert = 'Les données cartographiques sont temporairement indisponibles. Réessayez dans un instant.'
|
||||||
|
response.status = 503
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
champ = policy_scope(Champ).find(params[:champ_id])
|
||||||
|
geo_area = champ.geo_areas.selections_utilisateur.new
|
||||||
|
save_geometry!(geo_area, params_feature)
|
||||||
|
|
||||||
|
render json: { feature: geo_area.to_feature }, status: :created
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
champ = policy_scope(Champ).find(params[:champ_id])
|
||||||
|
geo_area = champ.geo_areas.selections_utilisateur.find(params[:id])
|
||||||
|
save_geometry!(geo_area, params_feature)
|
||||||
|
|
||||||
|
head :no_content
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
champ = policy_scope(Champ).find(params[:champ_id])
|
||||||
|
champ.geo_areas.selections_utilisateur.find(params[:id]).destroy!
|
||||||
|
|
||||||
|
head :no_content
|
||||||
|
end
|
||||||
|
|
||||||
|
def import
|
||||||
|
champ = policy_scope(Champ).find(params[:champ_id])
|
||||||
|
params_features.each do |feature|
|
||||||
|
geo_area = champ.geo_areas.selections_utilisateur.new
|
||||||
|
save_geometry!(geo_area, feature)
|
||||||
|
end
|
||||||
|
|
||||||
|
render json: champ.to_feature_collection, status: :created
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def populate_cadastres(feature_collection)
|
def populate_cadastres(feature_collection)
|
||||||
|
@ -61,4 +109,45 @@ class Champs::CarteController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def params_feature
|
||||||
|
params[:feature]
|
||||||
|
end
|
||||||
|
|
||||||
|
def params_features
|
||||||
|
params[:features]
|
||||||
|
end
|
||||||
|
|
||||||
|
def save_geometry!(geo_area, feature)
|
||||||
|
geo_area.geometry = feature[:geometry]
|
||||||
|
geo_area.save!
|
||||||
|
end
|
||||||
|
|
||||||
|
def cadastres_features_collection(feature_collection)
|
||||||
|
coordinates = feature_collection[:features].filter do |feature|
|
||||||
|
feature[:properties][:source] == GeoArea.sources.fetch(:selection_utilisateur) && feature[:geometry]['type'] == 'Polygon'
|
||||||
|
end.map do |feature|
|
||||||
|
feature[:geometry]['coordinates'][0].map { |(lng, lat)| { 'lng' => lng, 'lat' => lat } }
|
||||||
|
end
|
||||||
|
|
||||||
|
if coordinates.present?
|
||||||
|
cadastres = ApiCartoService.generate_cadastre(coordinates)
|
||||||
|
|
||||||
|
{
|
||||||
|
type: 'FeatureCollection',
|
||||||
|
features: cadastres.map do |cadastre|
|
||||||
|
{
|
||||||
|
type: 'Feature',
|
||||||
|
geometry: cadastre.delete(:geometry),
|
||||||
|
properties: cadastre.merge(source: GeoArea.sources.fetch(:cadastre))
|
||||||
|
}
|
||||||
|
end
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
type: 'FeatureCollection',
|
||||||
|
features: []
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -72,6 +72,14 @@ module Instructeurs
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def bilans_bdf
|
||||||
|
if avis.dossier.etablissement&.entreprise_bilans_bdf_to_csv.present?
|
||||||
|
render csv: avis.dossier.etablissement.entreprise_bilans_bdf_to_csv
|
||||||
|
else
|
||||||
|
redirect_to instructeur_avis_path(avis)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def sign_up
|
def sign_up
|
||||||
@email = params[:email]
|
@email = params[:email]
|
||||||
@dossier = Avis.includes(:dossier).find(params[:id]).dossier
|
@dossier = Avis.includes(:dossier).find(params[:id]).dossier
|
||||||
|
|
|
@ -692,6 +692,8 @@ type Effectif {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Entreprise {
|
type Entreprise {
|
||||||
|
attestationFiscaleAttachment: File
|
||||||
|
attestationSocialeAttachment: File
|
||||||
capitalSocial: BigInt!
|
capitalSocial: BigInt!
|
||||||
codeEffectifEntreprise: String!
|
codeEffectifEntreprise: String!
|
||||||
dateCreation: ISO8601Date!
|
dateCreation: ISO8601Date!
|
||||||
|
|
|
@ -21,6 +21,16 @@ module Types
|
||||||
field :nom, String, null: false
|
field :nom, String, null: false
|
||||||
field :prenom, String, null: false
|
field :prenom, String, null: false
|
||||||
field :inline_adresse, String, null: false
|
field :inline_adresse, String, null: false
|
||||||
|
field :attestation_sociale_attachment, Types::File, null: true
|
||||||
|
field :attestation_fiscale_attachment, Types::File, null: true
|
||||||
|
|
||||||
|
def attestation_sociale_attachment
|
||||||
|
load_attachment_for(:entreprise_attestation_sociale_attachment)
|
||||||
|
end
|
||||||
|
|
||||||
|
def attestation_fiscale_attachment
|
||||||
|
load_attachment_for(:entreprise_attestation_fiscale_attachment)
|
||||||
|
end
|
||||||
|
|
||||||
def effectif_mensuel
|
def effectif_mensuel
|
||||||
if object.effectif_mensuel.present?
|
if object.effectif_mensuel.present?
|
||||||
|
@ -39,6 +49,15 @@ module Types
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def load_attachment_for(key)
|
||||||
|
Loaders::Association.for(
|
||||||
|
Etablissement,
|
||||||
|
key => :blob
|
||||||
|
).load(object.etablissement)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class AssociationType < Types::BaseObject
|
class AssociationType < Types::BaseObject
|
||||||
|
|
|
@ -3,116 +3,122 @@ import PropTypes from 'prop-types';
|
||||||
import mapboxgl from 'mapbox-gl';
|
import mapboxgl from 'mapbox-gl';
|
||||||
import ReactMapboxGl, { GeoJSONLayer, ZoomControl } from 'react-mapbox-gl';
|
import ReactMapboxGl, { GeoJSONLayer, ZoomControl } from 'react-mapbox-gl';
|
||||||
import DrawControl from 'react-mapbox-gl-draw';
|
import DrawControl from 'react-mapbox-gl-draw';
|
||||||
import area from '@turf/area';
|
|
||||||
import SwitchMapStyle from './SwitchMapStyle';
|
import SwitchMapStyle from './SwitchMapStyle';
|
||||||
import SearchInput from './SearchInput';
|
import SearchInput from './SearchInput';
|
||||||
import { fire } from '@utils';
|
import { getJSON, ajax } from '@utils';
|
||||||
|
import { gpx } from '@tmcw/togeojson/dist/togeojson.es.js';
|
||||||
import ortho from './styles/ortho.json';
|
import ortho from './styles/ortho.json';
|
||||||
import vector from './styles/vector.json';
|
import vector from './styles/vector.json';
|
||||||
import {
|
import { polygonCadastresFill, polygonCadastresLine } from './utils';
|
||||||
createFeatureCollection,
|
|
||||||
polygonCadastresFill,
|
|
||||||
polygonCadastresLine,
|
|
||||||
ERROR_GEO_JSON
|
|
||||||
} from './utils';
|
|
||||||
import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css';
|
import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css';
|
||||||
|
|
||||||
const Map = ReactMapboxGl({});
|
const Map = ReactMapboxGl({});
|
||||||
|
|
||||||
const MapEditor = ({ featureCollection: { features, bbox, id } }) => {
|
function filterFeatureCollection(featureCollection, source) {
|
||||||
|
return {
|
||||||
|
type: 'FeatureCollection',
|
||||||
|
features: featureCollection.features.filter(
|
||||||
|
feature => feature.properties.source === source
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const MapEditor = ({ featureCollection, url }) => {
|
||||||
const drawControl = useRef(null);
|
const drawControl = useRef(null);
|
||||||
const [style, setStyle] = useState('ortho');
|
const [style, setStyle] = useState('ortho');
|
||||||
const [coords, setCoords] = useState([1.7, 46.9]);
|
const [coords, setCoords] = useState([1.7, 46.9]);
|
||||||
const [zoom, setZoom] = useState([5]);
|
const [zoom, setZoom] = useState([5]);
|
||||||
const [currentMap, setCurrentMap] = useState({});
|
const [currentMap, setCurrentMap] = useState({});
|
||||||
let input = document.querySelector(
|
const [bbox, setBbox] = useState(featureCollection.bbox);
|
||||||
`input[data-feature-collection-id="${id}"]`
|
|
||||||
);
|
|
||||||
|
|
||||||
let userSelections = features.filter(
|
|
||||||
feature => feature.properties.source === 'selection_utilisateur'
|
|
||||||
);
|
|
||||||
|
|
||||||
let cadastresFeatureCollection = {
|
|
||||||
type: 'FeatureCollection',
|
|
||||||
features: []
|
|
||||||
};
|
|
||||||
|
|
||||||
const constructCadastresFeatureCollection = features => {
|
|
||||||
for (let feature of features) {
|
|
||||||
switch (feature.properties.source) {
|
|
||||||
case 'cadastre':
|
|
||||||
cadastresFeatureCollection.features.push(feature);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
constructCadastresFeatureCollection(features);
|
|
||||||
|
|
||||||
const mapStyle = style === 'ortho' ? ortho : vector;
|
const mapStyle = style === 'ortho' ? ortho : vector;
|
||||||
|
const cadastresFeatureCollection = filterFeatureCollection(
|
||||||
const saveFeatureCollection = featuresToSave => {
|
featureCollection,
|
||||||
const featuresCollection = createFeatureCollection(featuresToSave);
|
'cadastre'
|
||||||
if (area(featuresCollection) < 300000) {
|
|
||||||
input.value = JSON.stringify(featuresCollection);
|
|
||||||
} else {
|
|
||||||
input.value = ERROR_GEO_JSON;
|
|
||||||
}
|
|
||||||
fire(input, 'change');
|
|
||||||
};
|
|
||||||
|
|
||||||
const onDrawCreate = ({ features }) => {
|
|
||||||
const draw = drawControl.current.draw;
|
|
||||||
const featureId = features[0].id;
|
|
||||||
draw.setFeatureProperty(featureId, 'id', featureId);
|
|
||||||
draw.setFeatureProperty(featureId, 'source', 'selection_utilisateur');
|
|
||||||
userSelections.push(draw.get(featureId));
|
|
||||||
saveFeatureCollection(userSelections);
|
|
||||||
};
|
|
||||||
|
|
||||||
const onDrawUpdate = ({ features }) => {
|
|
||||||
let featureId = features[0].properties.id;
|
|
||||||
userSelections = userSelections.map(selection => {
|
|
||||||
if (selection.properties.id === featureId) {
|
|
||||||
selection = features[0];
|
|
||||||
}
|
|
||||||
return selection;
|
|
||||||
});
|
|
||||||
saveFeatureCollection(userSelections);
|
|
||||||
};
|
|
||||||
|
|
||||||
const onDrawDelete = ({ features }) => {
|
|
||||||
userSelections = userSelections.filter(
|
|
||||||
selection => selection.properties.id !== features[0].properties.id
|
|
||||||
);
|
);
|
||||||
saveFeatureCollection(userSelections);
|
|
||||||
};
|
function updateFeaturesList(features) {
|
||||||
|
const cadastres = features.find(
|
||||||
|
({ geometry }) => geometry.type === 'Polygon'
|
||||||
|
);
|
||||||
|
ajax({ url, type: 'get', data: cadastres ? 'cadastres=update' : '' });
|
||||||
|
}
|
||||||
|
|
||||||
|
function setFeatureId(lid, feature) {
|
||||||
|
const draw = drawControl.current.draw;
|
||||||
|
draw.setFeatureProperty(lid, 'id', feature.properties.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onDrawCreate({ features }) {
|
||||||
|
for (const feature of features) {
|
||||||
|
const data = await getJSON(url, { feature }, 'post');
|
||||||
|
setFeatureId(feature.id, data.feature);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateFeaturesList(features);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onDrawUpdate({ features }) {
|
||||||
|
for (const feature of features) {
|
||||||
|
let { id } = feature.properties;
|
||||||
|
await getJSON(`${url}/${id}`, { feature }, 'patch');
|
||||||
|
}
|
||||||
|
|
||||||
|
updateFeaturesList(features);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onDrawDelete({ features }) {
|
||||||
|
for (const feature of features) {
|
||||||
|
const { id } = feature.properties;
|
||||||
|
await getJSON(`${url}/${id}`, null, 'delete');
|
||||||
|
}
|
||||||
|
|
||||||
|
updateFeaturesList(features);
|
||||||
|
}
|
||||||
|
|
||||||
const onMapLoad = map => {
|
const onMapLoad = map => {
|
||||||
setCurrentMap(map);
|
setCurrentMap(map);
|
||||||
if (userSelections.length > 0) {
|
|
||||||
userSelections.map((selection, index) => {
|
drawControl.current.draw.set(
|
||||||
selection.properties.id = index + 1;
|
filterFeatureCollection(featureCollection, 'selection_utilisateur')
|
||||||
drawControl.current.draw.add(selection);
|
);
|
||||||
});
|
};
|
||||||
|
|
||||||
|
const onCadastresUpdate = evt => {
|
||||||
|
if (currentMap) {
|
||||||
|
currentMap
|
||||||
|
.getSource('cadastres-layer')
|
||||||
|
.setData(
|
||||||
|
filterFeatureCollection(evt.detail.featureCollection, 'cadastre')
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onMapUpdate = evt => {
|
const onGpxImport = e => {
|
||||||
if (currentMap) {
|
let reader = new FileReader();
|
||||||
cadastresFeatureCollection.features = [];
|
reader.readAsText(e.target.files[0], 'UTF-8');
|
||||||
constructCadastresFeatureCollection(
|
reader.onload = async event => {
|
||||||
evt.detail.featureCollection.features
|
const featureCollection = gpx(
|
||||||
|
new DOMParser().parseFromString(event.target.result, 'text/xml')
|
||||||
);
|
);
|
||||||
currentMap
|
const resultFeatureCollection = await getJSON(
|
||||||
.getSource('cadastres-layer')
|
`${url}/import`,
|
||||||
.setData(cadastresFeatureCollection);
|
featureCollection,
|
||||||
}
|
'post'
|
||||||
|
);
|
||||||
|
drawControl.current.draw.set(
|
||||||
|
filterFeatureCollection(
|
||||||
|
resultFeatureCollection,
|
||||||
|
'selection_utilisateur'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
updateFeaturesList(resultFeatureCollection.features);
|
||||||
|
setBbox(resultFeatureCollection.bbox);
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
addEventListener('map:update', onMapUpdate);
|
addEventListener('cadastres:update', onCadastresUpdate);
|
||||||
return () => removeEventListener('map:update', onMapUpdate);
|
return () => removeEventListener('cadastres:update', onCadastresUpdate);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!mapboxgl.supported()) {
|
if (!mapboxgl.supported()) {
|
||||||
|
@ -127,6 +133,16 @@ const MapEditor = ({ featureCollection: { features, bbox, id } }) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<div className="file-import" style={{ marginBottom: '20px' }}>
|
||||||
|
<div>
|
||||||
|
<p style={{ fontWeight: 'bolder', marginBottom: '10px' }}>
|
||||||
|
Importer un fichier GPX
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<input type="file" accept=".gpx" onChange={onGpxImport} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
marginBottom: '62px'
|
marginBottom: '62px'
|
||||||
|
@ -193,7 +209,8 @@ MapEditor.propTypes = {
|
||||||
bbox: PropTypes.array,
|
bbox: PropTypes.array,
|
||||||
features: PropTypes.array,
|
features: PropTypes.array,
|
||||||
id: PropTypes.number
|
id: PropTypes.number
|
||||||
})
|
}),
|
||||||
|
url: PropTypes.string
|
||||||
};
|
};
|
||||||
|
|
||||||
export default MapEditor;
|
export default MapEditor;
|
||||||
|
|
|
@ -47,7 +47,7 @@ const SearchInput = ({ getCoords }) => {
|
||||||
return (
|
return (
|
||||||
<Combobox aria-label="addresses">
|
<Combobox aria-label="addresses">
|
||||||
<ComboboxInput
|
<ComboboxInput
|
||||||
placeholder="Saisissez au moins 2 caractères"
|
placeholder="Rechercher une adresse : saisissez au moins 2 caractères"
|
||||||
className="address-search-input"
|
className="address-search-input"
|
||||||
style={{
|
style={{
|
||||||
font: 'inherit',
|
font: 'inherit',
|
||||||
|
|
|
@ -1,11 +1,3 @@
|
||||||
export const ERROR_GEO_JSON = '';
|
|
||||||
export const createFeatureCollection = selectionsUtilisateur => {
|
|
||||||
return {
|
|
||||||
type: 'FeatureCollection',
|
|
||||||
features: selectionsUtilisateur
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const polygonCadastresFill = {
|
export const polygonCadastresFill = {
|
||||||
'fill-color': '#EC3323',
|
'fill-color': '#EC3323',
|
||||||
'fill-opacity': 0.3
|
'fill-opacity': 0.3
|
||||||
|
|
|
@ -68,7 +68,7 @@ export function ajax(options) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getJSON(url, data, method = 'get') {
|
export function getJSON(url, data, method = 'get') {
|
||||||
data = method !== 'get' ? JSON.stringify(data) : data;
|
data = method !== 'get' && data ? JSON.stringify(data) : data;
|
||||||
return Promise.resolve(
|
return Promise.resolve(
|
||||||
$.ajax({
|
$.ajax({
|
||||||
method,
|
method,
|
||||||
|
|
|
@ -3,6 +3,7 @@ class Entreprise < Hashie::Dash
|
||||||
self[attribute]
|
self[attribute]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
property :etablissement
|
||||||
property :siren
|
property :siren
|
||||||
property :capital_social
|
property :capital_social
|
||||||
property :numero_tva_intracommunautaire
|
property :numero_tva_intracommunautaire
|
||||||
|
|
|
@ -96,6 +96,7 @@ class Etablissement < ApplicationRecord
|
||||||
|
|
||||||
def entreprise
|
def entreprise
|
||||||
Entreprise.new(
|
Entreprise.new(
|
||||||
|
etablissement: self,
|
||||||
siren: entreprise_siren,
|
siren: entreprise_siren,
|
||||||
capital_social: entreprise_capital_social,
|
capital_social: entreprise_capital_social,
|
||||||
numero_tva_intracommunautaire: entreprise_numero_tva_intracommunautaire,
|
numero_tva_intracommunautaire: entreprise_numero_tva_intracommunautaire,
|
||||||
|
|
9
app/views/champs/carte/index.js.erb
Normal file
9
app/views/champs/carte/index.js.erb
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<%= render_flash(timeout: 5000, fixed: true) %>
|
||||||
|
|
||||||
|
<%= render_to_element("#{@selector} + .geo-areas",
|
||||||
|
partial: 'shared/champs/carte/geo_areas',
|
||||||
|
locals: { champ: @champ, error: @error }) %>
|
||||||
|
|
||||||
|
<% if @update_cadastres %>
|
||||||
|
<%= fire_event('cadastres:update', { featureCollection: @champ.to_feature_collection }.to_json) %>
|
||||||
|
<% end %>
|
|
@ -4,8 +4,4 @@
|
||||||
partial: 'shared/champs/carte/geo_areas',
|
partial: 'shared/champs/carte/geo_areas',
|
||||||
locals: { champ: @champ, error: @error }) %>
|
locals: { champ: @champ, error: @error }) %>
|
||||||
|
|
||||||
<% if feature_enabled?(:new_map_editor) %>
|
<%= fire_event('carte:update', { selector: @selector, data: @champ.to_render_data }.to_json) %>
|
||||||
<%= fire_event('map:update', { featureCollection: @champ.to_feature_collection }.to_json) %>
|
|
||||||
<% else %>
|
|
||||||
<%= fire_event('carte:update', { selector: @selector, data: @champ.to_render_data }.to_json) %>
|
|
||||||
<% end %>
|
|
||||||
|
|
|
@ -57,7 +57,11 @@ def render_identite_etablissement(pdf, etablissement)
|
||||||
pdf.text " - Libellé NAF : #{etablissement.libelle_naf}"
|
pdf.text " - Libellé NAF : #{etablissement.libelle_naf}"
|
||||||
pdf.text " - Code NAF : #{etablissement.naf}"
|
pdf.text " - Code NAF : #{etablissement.naf}"
|
||||||
pdf.text " - Date de création : #{try_format_date(etablissement.entreprise.date_creation)}"
|
pdf.text " - Date de création : #{try_format_date(etablissement.entreprise.date_creation)}"
|
||||||
pdf.text " - Effectif de l'organisation : #{effectif(etablissement)}"
|
if @include_infos_administration
|
||||||
|
pdf.text " - Effectif mensuel #{try_format_mois_effectif(etablissement)} (URSSAF) : #{etablissement.entreprise_effectif_mensuel}"
|
||||||
|
pdf.text " - Effectif moyen annuel #{etablissement.entreprise_effectif_annuel_annee} (URSSAF) : #{etablissement.entreprise_effectif_annuel}"
|
||||||
|
end
|
||||||
|
pdf.text " - Effectif de l'organisation (INSEE) : #{effectif(etablissement)}"
|
||||||
pdf.text " - Code effectif : #{etablissement.entreprise.code_effectif_entreprise}"
|
pdf.text " - Code effectif : #{etablissement.entreprise.code_effectif_entreprise}"
|
||||||
pdf.text " - Numéro de TVA intracommunautaire : #{etablissement.entreprise.numero_tva_intracommunautaire}"
|
pdf.text " - Numéro de TVA intracommunautaire : #{etablissement.entreprise.numero_tva_intracommunautaire}"
|
||||||
pdf.text " - Adresse : #{etablissement.adresse}"
|
pdf.text " - Adresse : #{etablissement.adresse}"
|
||||||
|
|
|
@ -83,7 +83,10 @@
|
||||||
%th.libelle
|
%th.libelle
|
||||||
Bilans Banque de France
|
Bilans Banque de France
|
||||||
= "en #{etablissement.entreprise_bilans_bdf_monnaie}"
|
= "en #{etablissement.entreprise_bilans_bdf_monnaie}"
|
||||||
%td= link_to "Consulter les bilans", bilans_bdf_instructeur_dossier_path
|
- if controller.is_a?(Instructeurs::AvisController)
|
||||||
|
%td= link_to "Consulter les bilans", bilans_bdf_instructeur_avis_path(@avis.id)
|
||||||
|
- else
|
||||||
|
%td= link_to "Consulter les bilans", bilans_bdf_instructeur_dossier_path(procedure_id: @dossier.procedure.id, dossier_id: @dossier.id)
|
||||||
|
|
||||||
- if etablissement.association?
|
- if etablissement.association?
|
||||||
%tr
|
%tr
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
|
|
||||||
- if feature_enabled?(:new_map_editor)
|
- if feature_enabled?(:new_map_editor)
|
||||||
= react_component("MapEditor", { featureCollection: champ.to_feature_collection }, class: "carte-#{form.index}")
|
= react_component("MapEditor", { featureCollection: champ.to_feature_collection, url: champs_carte_features_path(champ) }, class: "carte-#{champ.id}")
|
||||||
- else
|
- else
|
||||||
.toolbar
|
.toolbar
|
||||||
%button.button.primary.new-area Ajouter une zone
|
%button.button.primary.new-area Ajouter une zone
|
||||||
%select.select2.adresse{ data: { address: true }, placeholder: 'Saisissez une adresse ou positionner la carte' }
|
%select.select2.adresse{ data: { address: true }, placeholder: 'Saisissez une adresse ou positionner la carte' }
|
||||||
.carte.edit{ data: { geo: geo_data(champ) }, class: "carte-#{form.index}" }
|
.carte.edit{ data: { geo: geo_data(champ) }, class: "carte-#{form.index}" }
|
||||||
|
|
||||||
|
= form.hidden_field :value,
|
||||||
|
data: { remote: true, feature_collection_id: champ.stable_id, url: champs_carte_path(form.index), params: champ_carte_params(champ).to_query, method: 'post' }
|
||||||
|
|
||||||
.geo-areas
|
.geo-areas
|
||||||
= render partial: 'shared/champs/carte/geo_areas', locals: { champ: champ, error: false }
|
= render partial: 'shared/champs/carte/geo_areas', locals: { champ: champ, error: false }
|
||||||
|
|
||||||
= form.hidden_field :value,
|
|
||||||
data: { remote: true, feature_collection_id: champ.stable_id, url: champs_carte_path(form.index), params: champ_carte_params(champ).to_query, method: 'post' }
|
|
||||||
|
|
|
@ -120,6 +120,13 @@ Rails.application.routes.draw do
|
||||||
get ':position/siret', to: 'siret#show', as: :siret
|
get ':position/siret', to: 'siret#show', as: :siret
|
||||||
get ':position/dossier_link', to: 'dossier_link#show', as: :dossier_link
|
get ':position/dossier_link', to: 'dossier_link#show', as: :dossier_link
|
||||||
post ':position/carte', to: 'carte#show', as: :carte
|
post ':position/carte', to: 'carte#show', as: :carte
|
||||||
|
|
||||||
|
get ':champ_id/carte/features', to: 'carte#index', as: :carte_features
|
||||||
|
post ':champ_id/carte/features', to: 'carte#create'
|
||||||
|
post ':champ_id/carte/features/import', to: 'carte#import'
|
||||||
|
patch ':champ_id/carte/features/:id', to: 'carte#update'
|
||||||
|
delete ':champ_id/carte/features/:id', to: 'carte#destroy'
|
||||||
|
|
||||||
post ':position/repetition', to: 'repetition#show', as: :repetition
|
post ':position/repetition', to: 'repetition#show', as: :repetition
|
||||||
put 'piece_justificative/:champ_id', to: 'piece_justificative#update', as: :piece_justificative
|
put 'piece_justificative/:champ_id', to: 'piece_justificative#update', as: :piece_justificative
|
||||||
end
|
end
|
||||||
|
@ -347,6 +354,7 @@ Rails.application.routes.draw do
|
||||||
get 'messagerie'
|
get 'messagerie'
|
||||||
post 'commentaire' => 'avis#create_commentaire'
|
post 'commentaire' => 'avis#create_commentaire'
|
||||||
post 'avis' => 'avis#create_avis'
|
post 'avis' => 'avis#create_avis'
|
||||||
|
get 'bilans_bdf'
|
||||||
|
|
||||||
get 'sign_up/email/:email' => 'avis#sign_up', constraints: { email: /.*/ }, as: 'sign_up'
|
get 'sign_up/email/:email' => 'avis#sign_up', constraints: { email: /.*/ }, as: 'sign_up'
|
||||||
post 'sign_up/email/:email' => 'avis#create_instructeur', constraints: { email: /.*/ }
|
post 'sign_up/email/:email' => 'avis#create_instructeur', constraints: { email: /.*/ }
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
"@rails/webpacker": "4.2.2",
|
"@rails/webpacker": "4.2.2",
|
||||||
"@reach/combobox": "^0.10.0",
|
"@reach/combobox": "^0.10.0",
|
||||||
"@sentry/browser": "^5.11.2",
|
"@sentry/browser": "^5.11.2",
|
||||||
|
"@tmcw/togeojson": "^4.0.0",
|
||||||
"@turf/area": "^6.0.1",
|
"@turf/area": "^6.0.1",
|
||||||
"babel-plugin-macros": "^2.8.0",
|
"babel-plugin-macros": "^2.8.0",
|
||||||
"babel-plugin-transform-react-remove-prop-types": "^0.4.24",
|
"babel-plugin-transform-react-remove-prop-types": "^0.4.24",
|
||||||
|
|
|
@ -18,6 +18,126 @@ describe Champs::CarteController, type: :controller do
|
||||||
cadastres: true
|
cadastres: true
|
||||||
}).champ.create(dossier: dossier)
|
}).champ.create(dossier: dossier)
|
||||||
end
|
end
|
||||||
|
describe 'features' do
|
||||||
|
let(:feature) { attributes_for(:geo_area, :polygon) }
|
||||||
|
let(:geo_area) { create(:geo_area, :selection_utilisateur, :polygon, champ: champ) }
|
||||||
|
let(:params) do
|
||||||
|
{
|
||||||
|
champ_id: champ.id,
|
||||||
|
feature: feature
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
before do
|
||||||
|
sign_in user
|
||||||
|
request.accept = "application/json"
|
||||||
|
request.content_type = "application/json"
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'POST #create' do
|
||||||
|
before do
|
||||||
|
post :create, params: params
|
||||||
|
end
|
||||||
|
|
||||||
|
it { expect(response.status).to eq 201 }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'PATCH #update' do
|
||||||
|
let(:params) do
|
||||||
|
{
|
||||||
|
champ_id: champ.id,
|
||||||
|
id: geo_area.id,
|
||||||
|
feature: feature
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
before do
|
||||||
|
patch :update, params: params
|
||||||
|
end
|
||||||
|
|
||||||
|
it { expect(response.status).to eq 204 }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'DELETE #destroy' do
|
||||||
|
let(:params) do
|
||||||
|
{
|
||||||
|
champ_id: champ.id,
|
||||||
|
id: geo_area.id
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
before do
|
||||||
|
delete :destroy, params: params
|
||||||
|
end
|
||||||
|
|
||||||
|
it { expect(response.status).to eq 204 }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'POST #import' do
|
||||||
|
render_views
|
||||||
|
|
||||||
|
let(:params) do
|
||||||
|
{
|
||||||
|
champ_id: champ.id,
|
||||||
|
features: [feature]
|
||||||
|
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
before do
|
||||||
|
post :import, params: params
|
||||||
|
end
|
||||||
|
|
||||||
|
it {
|
||||||
|
expect(response.status).to eq 201
|
||||||
|
expect(response.body).to include("bbox")
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'GET #index' do
|
||||||
|
render_views
|
||||||
|
|
||||||
|
before do
|
||||||
|
request.accept = "application/javascript"
|
||||||
|
request.content_type = "application/javascript"
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with cadastres update' do
|
||||||
|
let(:params) do
|
||||||
|
{
|
||||||
|
champ_id: champ.id,
|
||||||
|
cadastres: 'update'
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
before do
|
||||||
|
get :index, params: params
|
||||||
|
end
|
||||||
|
|
||||||
|
it {
|
||||||
|
expect(response.status).to eq 200
|
||||||
|
expect(response.body).to include("DS.fire('cadastres:update'")
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'without cadastres update' do
|
||||||
|
let(:params) do
|
||||||
|
{
|
||||||
|
champ_id: champ.id
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
before do
|
||||||
|
get :index, params: params
|
||||||
|
end
|
||||||
|
|
||||||
|
it {
|
||||||
|
expect(response.status).to eq 200
|
||||||
|
expect(response.body).not_to include("DS.fire('cadastres:update'")
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe 'POST #show' do
|
describe 'POST #show' do
|
||||||
render_views
|
render_views
|
||||||
|
|
|
@ -50,6 +50,12 @@ describe Instructeurs::AvisController, type: :controller do
|
||||||
it { expect(assigns(:dossier)).to eq(dossier) }
|
it { expect(assigns(:dossier)).to eq(dossier) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#bilans_bdf' do
|
||||||
|
before { get :bilans_bdf, params: { id: avis_without_answer.id } }
|
||||||
|
|
||||||
|
it { expect(response).to redirect_to(instructeur_avis_path(avis_without_answer)) }
|
||||||
|
end
|
||||||
|
|
||||||
describe '#update' do
|
describe '#update' do
|
||||||
describe 'without attachment' do
|
describe 'without attachment' do
|
||||||
before do
|
before do
|
||||||
|
|
|
@ -133,13 +133,13 @@ describe DossierSearchService do
|
||||||
context 'when the user owns the dossier' do
|
context 'when the user owns the dossier' do
|
||||||
let(:terms) { dossier_0.id.to_s }
|
let(:terms) { dossier_0.id.to_s }
|
||||||
|
|
||||||
it { expect(subject.size).to eq(1) }
|
it { expect(subject.map(&:id)).to include(dossier_0.id) }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when the user does not own the dossier' do
|
context 'when the user does not own the dossier' do
|
||||||
let(:terms) { dossier_0b.id.to_s }
|
let(:terms) { dossier_0b.id.to_s }
|
||||||
|
|
||||||
it { expect(subject.size).to eq(0) }
|
it { expect(subject.map(&:id)).not_to include(dossier_0b.id) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1263,6 +1263,11 @@
|
||||||
"@sentry/types" "5.15.4"
|
"@sentry/types" "5.15.4"
|
||||||
tslib "^1.9.3"
|
tslib "^1.9.3"
|
||||||
|
|
||||||
|
"@tmcw/togeojson@^4.0.0":
|
||||||
|
version "4.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@tmcw/togeojson/-/togeojson-4.0.0.tgz#ee111e4e5b2b5d498d43e27a6c9bf546ce4041cc"
|
||||||
|
integrity sha512-JZXGC1myBPPYb/moq03cYPtErqZKzVR74Cv9C85IuqATHCxHCNOxw4D45vVcYHQnnxG2TQTIR+igzpbFiu/O6Q==
|
||||||
|
|
||||||
"@turf/area@^6.0.1":
|
"@turf/area@^6.0.1":
|
||||||
version "6.0.1"
|
version "6.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/@turf/area/-/area-6.0.1.tgz#50ed63c70ef2bdb72952384f1594319d94f3b051"
|
resolved "https://registry.yarnpkg.com/@turf/area/-/area-6.0.1.tgz#50ed63c70ef2bdb72952384f1594319d94f3b051"
|
||||||
|
|
Loading…
Reference in a new issue