apidae 0.11.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/apidae/application_controller.rb +19 -0
- data/app/controllers/apidae/dashboard_controller.rb +13 -4
- data/app/controllers/apidae/objects_controller.rb +6 -1
- data/app/controllers/apidae/projects_controller.rb +5 -1
- data/app/controllers/apidae/selections_controller.rb +6 -1
- data/app/helpers/apidae/application_helper.rb +4 -0
- data/app/models/apidae/apidae_data_parser.rb +376 -0
- data/app/models/apidae/obj.rb +19 -337
- data/db/migrate/20190127210921_migrate_localized_apidae_obj_fields.rb +9 -10
- data/db/migrate/20200522124205_rename_objs_contact_to_contact_data.rb +5 -0
- data/lib/apidae/version.rb +1 -1
- data/test/dummy/db/schema.rb +2 -2
- data/test/dummy/log/test.log +1864 -0
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '07291fb2c40fdbc091aff918c45c201602a5d58c'
|
4
|
+
data.tar.gz: 76f4566eb71404f129add27100872f1263ae868b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fa72db3de71d37e56b2c8908d703419a72fc5f0efd2d9f03ce91233ae0d68bd402f4a49d775fa22856a2109f83c7bb8bb54593224cc1e14377f696afc2e6d811
|
7
|
+
data.tar.gz: e1a0c2c71710947ea1b47266e2bb995ba5a44cec98190b3358168e21681ce9b2da4d3c479932514620929da4758affe03cece6e8693cf2f4458e327af108f7a8
|
@@ -2,5 +2,24 @@ module Apidae
|
|
2
2
|
class ApplicationController < ActionController::Base
|
3
3
|
protect_from_forgery with: :exception
|
4
4
|
before_action Rails.application.config.apidae_auth
|
5
|
+
before_action :check_user_data!
|
6
|
+
|
7
|
+
def apidae_user
|
8
|
+
send(Rails.application.config.apidae_user) if Rails.application.config.respond_to?(:apidae_user)
|
9
|
+
end
|
10
|
+
|
11
|
+
def user_is_admin?
|
12
|
+
apidae_user && Rails.application.config.respond_to?(:apidae_admin) && Rails.application.config.apidae_admin.call(apidae_user)
|
13
|
+
end
|
14
|
+
|
15
|
+
def user_has_data?
|
16
|
+
apidae_user && apidae_user.respond_to?(:apidae_projects_ids) && !apidae_user.apidae_projects_ids.blank?
|
17
|
+
end
|
18
|
+
|
19
|
+
def check_user_data!
|
20
|
+
unless user_has_data? || user_is_admin?
|
21
|
+
redirect_to main_app.root_path, alert: "Il n'y a aucun projet Apidae associé à votre compte."
|
22
|
+
end
|
23
|
+
end
|
5
24
|
end
|
6
25
|
end
|
@@ -3,11 +3,20 @@ require_dependency "apidae/application_controller"
|
|
3
3
|
module Apidae
|
4
4
|
class DashboardController < ApplicationController
|
5
5
|
def index
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
if user_is_admin?
|
7
|
+
@objects = Obj.count
|
8
|
+
@selections = Selection.count
|
9
|
+
@projects = Project.count
|
10
|
+
@last_imports = FileImport.order(id: :desc).take(100)
|
11
|
+
else
|
12
|
+
projects = Project.where(apidae_id: apidae_user.apidae_projects_ids)
|
13
|
+
selections = Selection.where(apidae_project_id: projects.select(:id).map {|p| p.id})
|
14
|
+
@projects = projects.count
|
15
|
+
@selections = selections.uniq.count
|
16
|
+
@objects = SelectionObject.where(apidae_selection_id: selections.map {|s| s.id}.uniq).map {|so| so.apidae_object_id}.uniq.count
|
17
|
+
@last_imports = FileImport.where(apidae_id: apidae_user.apidae_projects_ids).order(id: :desc).take(100)
|
18
|
+
end
|
9
19
|
@references = Reference.count
|
10
|
-
@last_imports = FileImport.order(id: :desc).take(100)
|
11
20
|
end
|
12
21
|
end
|
13
22
|
end
|
@@ -10,8 +10,13 @@ module Apidae
|
|
10
10
|
if params[:selection_id]
|
11
11
|
@selection = Selection.find(params[:selection_id])
|
12
12
|
@objects = @selection.objects.select(:id, :apidae_id, :title_data, :apidae_type, :updated_at)
|
13
|
-
|
13
|
+
elsif user_is_admin?
|
14
14
|
@objects = Obj.all.select(:id, :apidae_id, :title_data, :apidae_type, :updated_at)
|
15
|
+
else
|
16
|
+
projects_ids = Project.where(apidae_id: apidae_user.apidae_projects_ids).map {|p| p.id}
|
17
|
+
@objects = Obj.joins(:selections).where("apidae_selections.apidae_project_id IN (?)", projects_ids)
|
18
|
+
.select("apidae_objs.id, apidae_objs.apidae_id, apidae_objs.title_data, apidae_objs.apidae_type, apidae_objs.updated_at")
|
19
|
+
.distinct("apidae_objs.apidae_id").to_a
|
15
20
|
end
|
16
21
|
end
|
17
22
|
|
@@ -5,7 +5,11 @@ module Apidae
|
|
5
5
|
before_action :set_project, only: [:edit, :update, :destroy]
|
6
6
|
|
7
7
|
def index
|
8
|
-
|
8
|
+
if user_is_admin?
|
9
|
+
@projects = Project.all
|
10
|
+
else
|
11
|
+
@projects = Project.where(apidae_id: apidae_user.apidae_projects_ids)
|
12
|
+
end
|
9
13
|
end
|
10
14
|
|
11
15
|
def new
|
@@ -5,7 +5,12 @@ module Apidae
|
|
5
5
|
before_action :set_selection, only: [:show, :edit, :update, :destroy, :refresh]
|
6
6
|
|
7
7
|
def index
|
8
|
-
|
8
|
+
if user_is_admin?
|
9
|
+
@selections = Selection.all
|
10
|
+
else
|
11
|
+
projects_ids = Project.where(apidae_id: apidae_user.apidae_projects_ids).map {|p| p.id}
|
12
|
+
@selections = Selection.where(apidae_project_id: projects_ids)
|
13
|
+
end
|
9
14
|
end
|
10
15
|
|
11
16
|
def show
|
@@ -0,0 +1,376 @@
|
|
1
|
+
module Apidae
|
2
|
+
class ApidaeDataParser
|
3
|
+
PHONE = 201
|
4
|
+
EMAIL = 204
|
5
|
+
WEBSITE = 205
|
6
|
+
|
7
|
+
MODE_AUTO = 'auto'
|
8
|
+
MODE_MANUAL = 'manual'
|
9
|
+
|
10
|
+
MONDAY = 'MON'
|
11
|
+
TUESDAY = 'TUE'
|
12
|
+
WEDNESDAY = 'WED'
|
13
|
+
THURSDAY = 'THU'
|
14
|
+
FRIDAY = 'FRI'
|
15
|
+
SATURDAY = 'SAT'
|
16
|
+
SUNDAY = 'SUN'
|
17
|
+
|
18
|
+
ALL_DAYS = [MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY]
|
19
|
+
|
20
|
+
WEEKDAYS_MAP = {
|
21
|
+
'LUNDI' => MONDAY,
|
22
|
+
'MARDI' => TUESDAY,
|
23
|
+
'MERCREDI' => WEDNESDAY,
|
24
|
+
'JEUD' => THURSDAY,
|
25
|
+
'VENDREDI' => FRIDAY,
|
26
|
+
'SAMEDI' => SATURDAY,
|
27
|
+
'DIMANCHE' => SUNDAY
|
28
|
+
}
|
29
|
+
|
30
|
+
def self.parse_versioned_fields(data_hash)
|
31
|
+
version_fields = data_hash[:champsAspect] || []
|
32
|
+
matched_fields = []
|
33
|
+
version_fields.each do |f|
|
34
|
+
case f
|
35
|
+
when 'nom'
|
36
|
+
matched_fields << 'title'
|
37
|
+
when 'presentation.descriptifCourt'
|
38
|
+
matched_fields << 'short_desc'
|
39
|
+
when 'presentation.descriptifDetaille'
|
40
|
+
matched_fields << 'long_desc'
|
41
|
+
when 'illustrations'
|
42
|
+
matched_fields << 'pictures'
|
43
|
+
when 'multimedias'
|
44
|
+
matched_fields << 'attachments'
|
45
|
+
when 'informations.moyensCommunication'
|
46
|
+
matched_fields << 'contact'
|
47
|
+
when 'descriptifsThematises'
|
48
|
+
matched_fields << 'theme_desc'
|
49
|
+
when 'ouverture.periodesOuvertures', 'ouverture.periodeEnClair'
|
50
|
+
matched_fields << 'openings_desc'
|
51
|
+
matched_fields << 'openings'
|
52
|
+
when 'ouverture.periodeEnClairAutomatique'
|
53
|
+
matched_fields << 'openings_desc_mode'
|
54
|
+
when 'descriptionTarif.tarifsEnClair', 'descriptionTarif.periodes'
|
55
|
+
matched_fields << 'rates_desc'
|
56
|
+
matched_fields << 'rates'
|
57
|
+
when 'descriptionTarif.tarifsEnClairAutomatique'
|
58
|
+
matched_fields << 'rates_desc_mode'
|
59
|
+
when 'prestations.equipements'
|
60
|
+
matched_fields << 'equipments'
|
61
|
+
when 'prestations.activites'
|
62
|
+
matched_fields << 'activities'
|
63
|
+
when 'prestations.services'
|
64
|
+
matched_fields << 'services'
|
65
|
+
when 'localisation.environnements'
|
66
|
+
matched_fields << 'environments'
|
67
|
+
when 'prestations.complementAccueil'
|
68
|
+
matched_fields << 'extra'
|
69
|
+
when 'localisation.geolocalisation.complement'
|
70
|
+
matched_fields << 'access'
|
71
|
+
else
|
72
|
+
end
|
73
|
+
end
|
74
|
+
matched_fields.uniq
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.parse_title(data_hash, *locales)
|
78
|
+
{title: node_value(data_hash, :nom, *locales)}
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.parse_owner_data(data_hash)
|
82
|
+
unless data_hash.blank?
|
83
|
+
{owner_name: data_hash[:nom], owner_id: data_hash[:id]}
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.parse_desc_data(data_hash, private_data, *locales)
|
88
|
+
unless data_hash.blank?
|
89
|
+
{
|
90
|
+
short_desc: node_value(data_hash, :descriptifCourt, *locales),
|
91
|
+
long_desc: node_value(data_hash, :descriptifDetaille, *locales),
|
92
|
+
theme_desc: data_hash[:descriptifsThematises].blank? ? {} : Hash[data_hash[:descriptifsThematises].map {|th| [node_id(th, :theme), node_value(th, :description, *locales)]}],
|
93
|
+
private_desc: private_data.blank? ? {} : Hash[private_data.map {|d| [d[:nomTechnique], node_value(d, :descriptif, *locales)]}]
|
94
|
+
}
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.parse_pictures_data(pictures_array, *locales)
|
99
|
+
pics_data = {}
|
100
|
+
unless pictures_array.blank?
|
101
|
+
l = locales.blank? ? [DEFAULT_LOCALE] : locales
|
102
|
+
l.each do |locale|
|
103
|
+
pics_data[locale] = []
|
104
|
+
pictures_array.select { |p| p.is_a?(Hash) && !p[:traductionFichiers].blank? }.each do |pic|
|
105
|
+
pics_data[locale] << {
|
106
|
+
id: pic[:identifiant],
|
107
|
+
name: localized_value(pic, :nom, locale),
|
108
|
+
url: pic[:traductionFichiers][0][:url].gsub('http:', 'https:'),
|
109
|
+
description: localized_value(pic, :legende, locale),
|
110
|
+
credits: localized_value(pic, :copyright, locale),
|
111
|
+
expiration_date: pic[:dateLimiteDePublication]
|
112
|
+
}
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
{pictures: pics_data}
|
117
|
+
end
|
118
|
+
|
119
|
+
def self.parse_attachments_data(attachments_array, *locales)
|
120
|
+
atts_data = {}
|
121
|
+
unless attachments_array.blank?
|
122
|
+
l = locales.blank? ? [DEFAULT_LOCALE] : locales
|
123
|
+
l.each do |locale|
|
124
|
+
atts_data[locale] = []
|
125
|
+
attachments_array.select { |att| att.is_a?(Hash) && !att[:traductionFichiers].blank? }.each do |att|
|
126
|
+
atts_data[locale] << {
|
127
|
+
id: att[:identifiant],
|
128
|
+
name: localized_value(att, :nom, locale),
|
129
|
+
url: att[:traductionFichiers][0][:url].gsub('http:', 'https:'),
|
130
|
+
type: att[:type],
|
131
|
+
description: localized_value(att, :legende, locale)
|
132
|
+
}
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
{attachments: atts_data}
|
137
|
+
end
|
138
|
+
|
139
|
+
def self.parse_contact_data(information_hash, contacts_list)
|
140
|
+
contact_details = {contacts: contacts_list}
|
141
|
+
unless information_hash.blank?
|
142
|
+
contact_entries = information_hash[:moyensCommunication] || []
|
143
|
+
contact_entries.each do |c|
|
144
|
+
case c[:type][:id]
|
145
|
+
when PHONE
|
146
|
+
contact_details[:telephone] ||= []
|
147
|
+
contact_details[:telephone] << c[:coordonnees][:fr]
|
148
|
+
when EMAIL
|
149
|
+
contact_details[:email] ||= []
|
150
|
+
contact_details[:email] << c[:coordonnees][:fr]
|
151
|
+
when WEBSITE
|
152
|
+
contact_details[:website] ||= []
|
153
|
+
contact_details[:website] << c[:coordonnees][:fr]
|
154
|
+
else
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
contact_details
|
159
|
+
end
|
160
|
+
|
161
|
+
def self.parse_location_data(location_hash, type_data_hash, territories)
|
162
|
+
loc_data = {}
|
163
|
+
unless location_hash.blank?
|
164
|
+
address_hash = location_hash[:adresse]
|
165
|
+
computed_address = []
|
166
|
+
unless address_hash.blank?
|
167
|
+
computed_address << address_hash[:adresse1] unless address_hash[:adresse1].blank?
|
168
|
+
computed_address << address_hash[:adresse2] unless address_hash[:adresse2].blank?
|
169
|
+
computed_address << address_hash[:adresse3] unless address_hash[:adresse3].blank?
|
170
|
+
end
|
171
|
+
loc_data.merge!({address: computed_address})
|
172
|
+
loc_data.merge!({place: type_data_hash[:nomLieu]}) if type_data_hash
|
173
|
+
geoloc_details = location_hash[:geolocalisation]
|
174
|
+
if geoloc_details && geoloc_details[:valide] && geoloc_details[:geoJson]
|
175
|
+
loc_data[:latitude] = geoloc_details[:geoJson][:coordinates][1]
|
176
|
+
loc_data[:longitude] = geoloc_details[:geoJson][:coordinates][0]
|
177
|
+
end
|
178
|
+
loc_data[:access] = node_value(geoloc_details, :complement) if geoloc_details
|
179
|
+
loc_data[:environments] = location_hash[:environnements].map {|e| e[:id]} if location_hash[:environnements]
|
180
|
+
end
|
181
|
+
loc_data[:territories] = territories.map {|t| t[:id]} unless territories.blank?
|
182
|
+
loc_data
|
183
|
+
end
|
184
|
+
|
185
|
+
# Note : use internal format for openings storage (ideally Apihours one, to merge data from both sources)
|
186
|
+
def self.parse_openings(openings_hash, *locales)
|
187
|
+
if openings_hash && openings_hash[:periodeEnClair]
|
188
|
+
{
|
189
|
+
openings_desc: node_value(openings_hash, :periodeEnClair, *locales),
|
190
|
+
openings_desc_mode: openings_hash[:periodeEnClairGenerationMode] == 'AUTOMATIQUE' ? MODE_AUTO : MODE_MANUAL,
|
191
|
+
openings: build_openings(openings_hash, *locales),
|
192
|
+
time_periods: lists_ids(openings_hash[:indicationsPeriode])
|
193
|
+
}
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
def self.parse_rates(rates_hash, *locales)
|
198
|
+
if rates_hash
|
199
|
+
desc = rates_hash[:gratuit] ? {DEFAULT_LOCALE => 'gratuit'} : node_value(rates_hash, :tarifsEnClair, *locales)
|
200
|
+
values = rates_hash[:periodes].blank? ? [] : rates_hash[:periodes].map {|p| build_rate(p)}
|
201
|
+
methods = rates_hash[:modesPaiement].blank? ? [] : rates_hash[:modesPaiement].map {|p| p[:id]}
|
202
|
+
{
|
203
|
+
rates_desc: desc, rates: values, payment_methods: methods,
|
204
|
+
rates_desc_mode: rates_hash[:tarifsEnClairGenerationMode] == 'AUTOMATIQUE' ? MODE_AUTO : MODE_MANUAL,
|
205
|
+
includes: node_value(rates_hash, :leTarifComprend, *locales),
|
206
|
+
excludes: node_value(rates_hash, :leTarifNeComprendPas, *locales)
|
207
|
+
}
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
def self.parse_type_data(apidae_obj, type_hash, presta_hash, business_hash, *locales)
|
212
|
+
data_hash = type_hash || {}
|
213
|
+
prestations_hash = presta_hash || {}
|
214
|
+
apidae_obj.apidae_subtype = lists_ids(data_hash[:typesManifestation]).first if apidae_obj.apidae_type == Obj::FEM
|
215
|
+
apidae_obj.apidae_subtype = node_id(data_hash, :rubrique) if apidae_obj.apidae_type == Obj::EQU
|
216
|
+
apidae_obj.apidae_subtype = lists_ids(data_hash[:typesHebergement]).first if apidae_obj.apidae_type == Obj::SPA
|
217
|
+
{
|
218
|
+
categories: lists_ids(data_hash[:categories], data_hash[:typesDetailles], data_hash[:activiteCategories]),
|
219
|
+
themes: lists_ids(data_hash[:themes]),
|
220
|
+
capacity: (data_hash[:capacite] || {})
|
221
|
+
.merge(presta_hash ? {group_min: presta_hash[:tailleGroupeMin], group_max: presta_hash[:tailleGroupeMax],
|
222
|
+
age_min: presta_hash[:ageMin], age_max: presta_hash[:ageMax]} : {}),
|
223
|
+
classification: nodes_ids(data_hash[:classement], data_hash[:classementPrefectoral], data_hash[:classification]) +
|
224
|
+
lists_ids(data_hash[:classementsGuides]) + lists_ids(data_hash[:classements]),
|
225
|
+
labels: lists_ids(data_hash[:labels], data_hash[:labelsChartesQualite], prestations_hash[:labelsTourismeHandicap]) +
|
226
|
+
(node_id(data_hash, :typeLabel) ? [node_id(data_hash, :typeLabel)] : []),
|
227
|
+
chains: lists_ids(data_hash[:chaines]) + nodes_ids(data_hash[:chaineEtLabel]),
|
228
|
+
area: apidae_obj.apidae_type == Obj::DOS ? data_hash.except(:classification) : node_value(data_hash, :lieuDePratique),
|
229
|
+
track: apidae_obj.apidae_type == Obj::EQU ? data_hash[:itineraire] : nil,
|
230
|
+
products: lists_ids(data_hash[:typesProduit], data_hash[:aopAocIgps], data_hash[:specialites]),
|
231
|
+
audience: lists_ids(prestations_hash[:typesClientele]),
|
232
|
+
animals: prestations_hash[:animauxAcceptes] == 'ACCEPTES',
|
233
|
+
extra: apidae_obj.apidae_type == Obj::SPA ? node_value(data_hash, :formuleHebergement, *locales) : node_value(prestations_hash, :complementAccueil, *locales),
|
234
|
+
duration: apidae_obj.apidae_type == Obj::SPA ? {days: data_hash[:nombreJours], nights: data_hash[:nombreNuits]} : data_hash[:dureeSeance],
|
235
|
+
certifications: data_hash[:agrements].blank? ? [] : data_hash[:agrements].map {|a| {id: a[:type][:id], identifier: a[:numero]}},
|
236
|
+
business: business_hash
|
237
|
+
}
|
238
|
+
end
|
239
|
+
|
240
|
+
def self.parse_service_data(data_hash, type_data_hash)
|
241
|
+
if data_hash
|
242
|
+
{
|
243
|
+
services: lists_ids(data_hash[:services]),
|
244
|
+
equipments: lists_ids(data_hash[:equipements]),
|
245
|
+
comfort: lists_ids(data_hash[:conforts]),
|
246
|
+
activities: lists_ids(data_hash[:activites], type_data_hash ? type_data_hash[:activites] : [],
|
247
|
+
type_data_hash ? type_data_hash[:activitesSportives] : [],
|
248
|
+
type_data_hash ? type_data_hash[:activitesCulturelles] : []),
|
249
|
+
challenged: lists_ids(data_hash[:tourismesAdaptes]),
|
250
|
+
languages: lists_ids(data_hash[:languesParlees])
|
251
|
+
}
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
def self.parse_tags_data(pres_data_hash, crit_data_hash, linked_data_hash)
|
256
|
+
tags = {}
|
257
|
+
if pres_data_hash
|
258
|
+
tags[:promo] = lists_ids(pres_data_hash[:typologiesPromoSitra])
|
259
|
+
end
|
260
|
+
unless crit_data_hash.blank?
|
261
|
+
tags[:internal] = crit_data_hash.map {|c| c[:id]}
|
262
|
+
end
|
263
|
+
unless linked_data_hash.blank? || linked_data_hash[:liensObjetsTouristiquesTypes].blank?
|
264
|
+
tags[:linked] = linked_data_hash[:liensObjetsTouristiquesTypes]
|
265
|
+
.map {|l| {apidae_id: l[:objetTouristique][:id], apidae_type: l[:objetTouristique][:type], category: l[:type]}}
|
266
|
+
end
|
267
|
+
tags
|
268
|
+
end
|
269
|
+
|
270
|
+
def self.parse_booking(reservation_hash, *locales)
|
271
|
+
if reservation_hash
|
272
|
+
{
|
273
|
+
booking_desc: node_value(reservation_hash, :complement, *locales),
|
274
|
+
booking_entities: reservation_hash[:organismes]
|
275
|
+
}
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
def self.parse_town(location_hash)
|
280
|
+
if location_hash
|
281
|
+
address_hash = location_hash[:adresse]
|
282
|
+
(!address_hash.blank? && address_hash[:commune]) ? Town.find_by_apidae_id(address_hash[:commune][:id]) : nil
|
283
|
+
else
|
284
|
+
nil
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
def self.parse_entity_fields(information_hash, type_data_hash)
|
289
|
+
if information_hash && information_hash[:structureGestion]
|
290
|
+
{entity_id: information_hash[:structureGestion][:id], service_provider_id: node_id(type_data_hash, :prestataireActivites)}
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
def self.node_id(node, key)
|
295
|
+
node[key][:id] if node && node[key]
|
296
|
+
end
|
297
|
+
|
298
|
+
private
|
299
|
+
|
300
|
+
def self.build_rate(rate_period)
|
301
|
+
{
|
302
|
+
id: rate_period[:identifiant], start_date: rate_period[:dateDebut], end_date: rate_period[:dateFin],
|
303
|
+
values: rate_period[:tarifs].blank? ? [] : rate_period[:tarifs].map {|t| {min: t[:minimum], max: t[:maximum], type: t[:type][:id], details: node_value(t, :precisionTarif)}}
|
304
|
+
}
|
305
|
+
end
|
306
|
+
|
307
|
+
def self.build_openings(openings_data, *locales)
|
308
|
+
openings_list = openings_data[:periodesOuvertures]
|
309
|
+
closing_days = openings_data[:fermeturesExceptionnelles]
|
310
|
+
if openings_list.blank?
|
311
|
+
[]
|
312
|
+
else
|
313
|
+
openings_list.map do |o|
|
314
|
+
{
|
315
|
+
id: o[:identifiant],
|
316
|
+
external_id: o[:identifiantTechnique],
|
317
|
+
start_date: o[:dateDebut],
|
318
|
+
end_date: o[:dateFin],
|
319
|
+
closing_days: closing_days.blank? ? [] : closing_days.map {|d| d[:dateSpeciale]},
|
320
|
+
details: node_value(o, :complementHoraire, *locales),
|
321
|
+
time_periods: [
|
322
|
+
{
|
323
|
+
type: 'opening',
|
324
|
+
weekdays: compute_weekdays(o),
|
325
|
+
time_frames: (o[:horaireOuverture].blank? && o[:horaireFermeture].blank?) ? [] : [{start_time: o[:horaireOuverture], end_time: o[:horaireFermeture], recurrence: nil}]
|
326
|
+
}
|
327
|
+
]
|
328
|
+
}
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
def self.compute_weekdays(opening_data)
|
334
|
+
if opening_data[:type] == 'OUVERTURE_TOUS_LES_JOURS'
|
335
|
+
ALL_DAYS
|
336
|
+
elsif opening_data[:type] == 'OUVERTURE_SAUF' && opening_data[:ouverturesJournalieres]
|
337
|
+
closed_weekdays = opening_data[:ouverturesJournalieres].map {|d| WEEKDAYS_MAP[d[:jour]]}
|
338
|
+
ALL_DAYS - closed_weekdays
|
339
|
+
elsif opening_data[:type] == 'OUVERTURE_SEMAINE' && opening_data[:ouverturesJournalieres]
|
340
|
+
opening_data[:ouverturesJournalieres].map {|d| WEEKDAYS_MAP[d[:jour]]}
|
341
|
+
else
|
342
|
+
[]
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
346
|
+
def self.node_value(node, key, *locales)
|
347
|
+
l = locales.blank? ? [DEFAULT_LOCALE] : locales
|
348
|
+
locales_map = Hash[l.map {|loc| [localized_key(loc), loc]}]
|
349
|
+
if node && node[key]
|
350
|
+
node[key].slice(*locales_map.keys).transform_keys {|k| locales_map[k]}
|
351
|
+
else
|
352
|
+
{}
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
def self.localized_value(node, key, loc)
|
357
|
+
if node && node[key]
|
358
|
+
node[key][localized_key(loc)]
|
359
|
+
else
|
360
|
+
''
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
def self.lists_ids(*lists)
|
365
|
+
lists.blank? ? [] : lists.map {|l| l.blank? ? [] : l.map {|elt| elt[:id]}}.flatten.uniq
|
366
|
+
end
|
367
|
+
|
368
|
+
def self.nodes_ids(*nodes)
|
369
|
+
nodes.blank? ? [] : nodes.select {|n| !n.blank?}.map {|n| n[:id]}
|
370
|
+
end
|
371
|
+
|
372
|
+
def self.localized_key(loc = DEFAULT_LOCALE)
|
373
|
+
"libelle#{loc.camelize.gsub('-', '')}".to_sym
|
374
|
+
end
|
375
|
+
end
|
376
|
+
end
|