diff --git a/app/assets/javascripts/spree_cm_commissioner/routes.js b/app/assets/javascripts/spree_cm_commissioner/routes.js index 343d92018..0a149eea8 100644 --- a/app/assets/javascripts/spree_cm_commissioner/routes.js +++ b/app/assets/javascripts/spree_cm_commissioner/routes.js @@ -4,4 +4,8 @@ Spree.routes.seat_number_layouts_api_v2 = Spree.pathFor( Spree.routes.homepage_section_relatables_api_v2 = Spree.pathFor( "/api/v2/platform/homepage_section_relatable_options" -); \ No newline at end of file +); + +Spree.routes.product_places_api_v2 = Spree.pathFor( + "/api/v2/platform/product_places" +); diff --git a/app/controllers/spree/admin/nearby_places_controller.rb b/app/controllers/spree/admin/nearby_places_controller.rb index e5a085b53..255a47fe4 100644 --- a/app/controllers/spree/admin/nearby_places_controller.rb +++ b/app/controllers/spree/admin/nearby_places_controller.rb @@ -2,11 +2,17 @@ module Spree module Admin class NearbyPlacesController < Spree::Admin::ResourceController before_action :load_vendor + before_action :list_nearby_places, only: :new def index @nearby_places = @vendor.nearby_places end + def list_nearby_places + context = SpreeCmCommissioner::VendorNearbyPlaceBuilder.call(vendor: @vendor) + @list_nearby_places = context.nearby_places.sort_by(&:distance).take(10) + end + def new @name = params[:name] context = SpreeCmCommissioner::VendorNearbyPlaceBuilder.call(vendor: @vendor, name: @name) diff --git a/app/controllers/spree/admin/product_places_controller.rb b/app/controllers/spree/admin/product_places_controller.rb index f6350b249..4ca771de6 100644 --- a/app/controllers/spree/admin/product_places_controller.rb +++ b/app/controllers/spree/admin/product_places_controller.rb @@ -16,8 +16,14 @@ def new end def create + place_id = params.dig(:spree_cm_commissioner_product_place, :name) + place = SpreeCmCommissioner::Place.find_or_initialize_by(reference: place_id) + + update_place_from_google(place, place_id) if place.new_record? + @product_place = SpreeCmCommissioner::ProductPlace.new(permitted_resource_params) @product_place.product = parent + @product_place.place_id = place.id if @product_place.place_id.blank? flash[:error] = I18n.t('product_place.place_required') @@ -60,6 +66,24 @@ def update_positions private + def update_place_from_google(place, place_id) + context = SpreeCmCommissioner::GooglePlaceFetcher.call(reference: place_id) + + flash[:error] = Spree.t('product_place.empty_info') if context.google_place.blank? + + google_place = context.google_place.first + place.assign_attributes( + name: google_place.name, + vicinity: google_place.vicinity, + lat: google_place.lat, + lon: google_place.lon, + icon: google_place.icon, + rating: google_place.rating, + types: google_place.types + ) + place.save! + end + def filter_product_places(type) if type.present? parent.product_places.where(type: SpreeCmCommissioner::ProductPlace.types[type]) diff --git a/app/controllers/spree/api/v2/platform/product_places_controller.rb b/app/controllers/spree/api/v2/platform/product_places_controller.rb new file mode 100644 index 000000000..f2c95b4da --- /dev/null +++ b/app/controllers/spree/api/v2/platform/product_places_controller.rb @@ -0,0 +1,66 @@ +module Spree + module Api + module V2 + module Platform + class ProductPlacesController < ResourceController + respond_to :json + + def index + result = collection_serializer.new(collection).serializable_hash + + respond_with(result) do |format| + format.json { render json: result } + end + end + + def collection + @collection ||= begin + filter = params[:filter] || {} + name_filter = filter[:name_i_cont] + + new_places = SpreeCmCommissioner::GooglePlacesFetcher.call(name: name_filter) + + if new_places.success? + place_struct(new_places.google_places) + else + [] + end + end + end + + def model_class + SpreeCmCommissioner::ProductPlace + end + + def resource_serializer + SpreeCmCommissioner::Api::V2::Platform::ProductPlaceSerializer + end + + def collection_serializer + SpreeCmCommissioner::Api::V2::Platform::ProductPlaceSerializer + end + + private + + def place_struct(places) + places.each_with_index.map do |place| + PlaceWithId.new( + place.reference, + place.reference, + place.name, + place.vicinity, + place.lat, + place.lon, + place.icon, + place.rating, + place.types + ) + end + end + + PlaceWithId = Struct.new(:id, :reference, :name, :vicinity, :lat, :lon, :icon, :rating, :types) + end + end + end + end +end diff --git a/app/interactors/spree_cm_commissioner/google_place_fetcher.rb b/app/interactors/spree_cm_commissioner/google_place_fetcher.rb new file mode 100644 index 000000000..076f5ee3a --- /dev/null +++ b/app/interactors/spree_cm_commissioner/google_place_fetcher.rb @@ -0,0 +1,39 @@ +module SpreeCmCommissioner + class GooglePlaceFetcher < BaseInteractor + delegate :reference, to: :context + + def call + context.google_place = [] + json_response = fetch_google_place_by_reference + + json = json_response['result'] + place = SpreeCmCommissioner::Place.new( + reference: json['reference'], + types: json['types'].blank? ? '' : json['types'][0], + name: json['name'], + vicinity: json['vicinity'], + lat: json['geometry']['location']['lat'], + lon: json['geometry']['location']['lng'], + icon: json['icon'], + rating: json['rating'] + ) + context.google_place << place + end + + private + + def google_map_key + @google_map_key ||= ENV.fetch('GOOGLE_MAP_KEY') + end + + def fetch_google_place_by_reference + url = URI("#{GOOGLE_MAP_API_URL}/place/details/json?placeid=#{reference}&key=#{google_map_key}") + https = Net::HTTP.new(url.host, url.port) + https.use_ssl = true + + request = Net::HTTP::Get.new(url) + response = https.request(request) + JSON.parse(response.read_body) + end + end +end diff --git a/app/interactors/spree_cm_commissioner/google_places_fetcher.rb b/app/interactors/spree_cm_commissioner/google_places_fetcher.rb new file mode 100644 index 000000000..5c937da38 --- /dev/null +++ b/app/interactors/spree_cm_commissioner/google_places_fetcher.rb @@ -0,0 +1,41 @@ +module SpreeCmCommissioner + class GooglePlacesFetcher < BaseInteractor + delegate :name, to: :context + + def call + context.google_places = [] + json_response = fetch_google_place_by_name + + json_response['results'].each_with_index do |json, _| + place = SpreeCmCommissioner::Place.new( + reference: json['reference'], + types: json['types'].blank? ? '' : json['types'][0], + name: json['name'], + vicinity: json['vicinity'], + lat: json['geometry']['location']['lat'], + lon: json['geometry']['location']['lng'], + icon: json['icon'], + rating: json['rating'] + ) + + context.google_places << place + end + end + + private + + def google_map_key + @google_map_key ||= ENV.fetch('GOOGLE_MAP_KEY') + end + + def fetch_google_place_by_name + url = URI("#{GOOGLE_MAP_API_URL}/place/textsearch/json?query=#{name}&key=#{google_map_key}") + https = Net::HTTP.new(url.host, url.port) + https.use_ssl = true + + request = Net::HTTP::Get.new(url) + response = https.request(request) + JSON.parse(response.read_body) + end + end +end diff --git a/app/serializers/spree_cm_commissioner/api/v2/platform/product_place_serializer.rb b/app/serializers/spree_cm_commissioner/api/v2/platform/product_place_serializer.rb new file mode 100644 index 000000000..6a7734e77 --- /dev/null +++ b/app/serializers/spree_cm_commissioner/api/v2/platform/product_place_serializer.rb @@ -0,0 +1,11 @@ +module SpreeCmCommissioner + module Api + module V2 + module Platform + class ProductPlaceSerializer < ::Spree::Api::V2::Platform::BaseSerializer + attributes :id, :name, :reference, :lat, :lon, :rating, :types + end + end + end + end +end diff --git a/app/views/spree/admin/nearby_places/new.html.erb b/app/views/spree/admin/nearby_places/new.html.erb index f02722941..0ba66773e 100644 --- a/app/views/spree/admin/nearby_places/new.html.erb +++ b/app/views/spree/admin/nearby_places/new.html.erb @@ -4,7 +4,25 @@