From 2183645aae56dc20895acd071253ef67c0d67fac Mon Sep 17 00:00:00 2001 From: sreyleak Date: Fri, 22 Nov 2024 08:38:00 +0700 Subject: [PATCH] Close #1979: Create API for upcoming and previous events on the organizer profile screen --- .../api/v2/storefront/events_controller.rb | 27 ++++++++++++ .../admin/taxons/_form/vendor.html.erb.deface | 11 +++++ .../organizer_profile_event_query.rb | 28 ++++++++++++ .../storefront/taxon_serializer_decorator.rb | 2 +- .../spree_permitted_attributes.rb | 1 + config/routes.rb | 1 + ...0240926044328_add_vendor_to_spree_taxon.rb | 5 +++ .../organizer_profile_event_query_spec.rb | 43 +++++++++++++++++++ .../v2/storefront/taxon_serializer_spec.rb | 3 +- 9 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 app/controllers/spree/api/v2/storefront/events_controller.rb create mode 100644 app/overrides/spree/admin/taxons/_form/vendor.html.erb.deface create mode 100644 app/queries/spree_cm_commissioner/organizer_profile_event_query.rb create mode 100644 db/migrate/20240926044328_add_vendor_to_spree_taxon.rb create mode 100644 spec/queries/spree_cm_commissioner/organizer_profile_event_query_spec.rb diff --git a/app/controllers/spree/api/v2/storefront/events_controller.rb b/app/controllers/spree/api/v2/storefront/events_controller.rb new file mode 100644 index 000000000..4db383936 --- /dev/null +++ b/app/controllers/spree/api/v2/storefront/events_controller.rb @@ -0,0 +1,27 @@ +module Spree + module Api + module V2 + module Storefront + class EventsController < Spree::Api::V2::ResourceController + def collection + events_query.events.page(params[:page]).per(params[:per_page]) + end + + def collection_serializer + Spree::V2::Storefront::TaxonSerializer + end + + private + + def events_query + SpreeCmCommissioner::OrganizerProfileEventQuery.new( + vendor_id: params[:vendor_id], + section: params.fetch(:section, 'upcoming'), + start_from_date: params[:start_from_date] || nil + ) + end + end + end + end + end +end diff --git a/app/overrides/spree/admin/taxons/_form/vendor.html.erb.deface b/app/overrides/spree/admin/taxons/_form/vendor.html.erb.deface new file mode 100644 index 000000000..0eba3a10f --- /dev/null +++ b/app/overrides/spree/admin/taxons/_form/vendor.html.erb.deface @@ -0,0 +1,11 @@ + + +<% if @taxon.depth == 1 %> +
+ <%= f.field_container :vendor_id do %> + <%= label_tag :vendor_id, Spree.t(:vendors) %> + <%= f.select :vendor_id, Spree::Vendor.pluck(:name, :id), { include_blank: true }, { class: 'select2-clear js-filterable' } %> + <%= f.error_message_on :vendor_id, class: 'error-message' %> + <% end %> +
+<% end %> diff --git a/app/queries/spree_cm_commissioner/organizer_profile_event_query.rb b/app/queries/spree_cm_commissioner/organizer_profile_event_query.rb new file mode 100644 index 000000000..9c03666b7 --- /dev/null +++ b/app/queries/spree_cm_commissioner/organizer_profile_event_query.rb @@ -0,0 +1,28 @@ +module SpreeCmCommissioner + class OrganizerProfileEventQuery + attr_reader :vendor_id, :section, :start_from_date + + # user_id: user ID, vendor_id: vendor ID, section: 'upcoming', 'previous' or 'all' + def initialize(vendor_id:, section:, start_from_date: nil) + @vendor_id = vendor_id + @section = section + @start_from_date = start_from_date || Time.zone.now + end + + def events + taxons = Spree::Taxon.where(vendor_id: vendor_id) + + case section + when 'upcoming' + taxons.where('to_date >= ?', start_from_date) + .order(from_date: :asc) + when 'previous' + taxons.where('to_date < ?', start_from_date) + .order(to_date: :desc) + else + taxons.where('to_date >= ? OR to_date < ?', start_from_date, start_from_date) + .order(from_date: :asc) + end + end + end +end diff --git a/app/serializers/spree/v2/storefront/taxon_serializer_decorator.rb b/app/serializers/spree/v2/storefront/taxon_serializer_decorator.rb index fc8535756..5a12d8ddc 100644 --- a/app/serializers/spree/v2/storefront/taxon_serializer_decorator.rb +++ b/app/serializers/spree/v2/storefront/taxon_serializer_decorator.rb @@ -13,7 +13,7 @@ def self.prepended(base) base.attributes :custom_redirect_url, :kind, :subtitle, :from_date, :to_date, :background_color, :foreground_color, :show_badge_status, - :purchasable_on + :purchasable_on, :vendor_id base.attribute :purchasable_on_app do |taxon| taxon.purchasable_on == 'app' || taxon.purchasable_on == 'both' diff --git a/config/initializers/spree_permitted_attributes.rb b/config/initializers/spree_permitted_attributes.rb index 7849725aa..93147e6c3 100644 --- a/config/initializers/spree_permitted_attributes.rb +++ b/config/initializers/spree_permitted_attributes.rb @@ -28,6 +28,7 @@ module PermittedAttributes preferred_foreground_color show_badge_status purchasable_on + vendor_id ] @@store_attributes += [ diff --git a/config/routes.rb b/config/routes.rb index f7d497bef..488449b07 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -440,6 +440,7 @@ resources :vendors do resources :nearby_places, only: %i[index] resources :vendor_photos + resources :events end resource :homepage_data, only: [:show] resources :homepage_sections, only: [:index] diff --git a/db/migrate/20240926044328_add_vendor_to_spree_taxon.rb b/db/migrate/20240926044328_add_vendor_to_spree_taxon.rb new file mode 100644 index 000000000..18ebbe11b --- /dev/null +++ b/db/migrate/20240926044328_add_vendor_to_spree_taxon.rb @@ -0,0 +1,5 @@ +class AddVendorToSpreeTaxon < ActiveRecord::Migration[7.0] + def change + add_reference :spree_taxons, :vendor, index: true, foreign_key: { to_table: :spree_vendors }, if_not_exists: true + end +end diff --git a/spec/queries/spree_cm_commissioner/organizer_profile_event_query_spec.rb b/spec/queries/spree_cm_commissioner/organizer_profile_event_query_spec.rb new file mode 100644 index 000000000..5ac4a27f0 --- /dev/null +++ b/spec/queries/spree_cm_commissioner/organizer_profile_event_query_spec.rb @@ -0,0 +1,43 @@ +require 'spec_helper' + +RSpec.describe SpreeCmCommissioner::OrganizerProfileEventQuery do + let(:vendor) { create(:vendor) } + let(:start_from_date) { Time.zone.now } + let!(:upcoming_taxon) { create(:taxon, vendor_id: vendor.id, from_date: 1.day.from_now, to_date: 5.days.from_now) } + let!(:previous_taxon) { create(:taxon, vendor_id: vendor.id, from_date: 10.days.ago, to_date: 1.day.ago) } + + describe '#events' do + context 'when section is upcoming' do + it 'returns only upcoming events for the vendor' do + query = described_class.new(vendor_id: vendor.id, section: 'upcoming', start_from_date: start_from_date) + expect(query.events).to contain_exactly(upcoming_taxon) + end + end + + context 'when section is previous' do + it 'returns only previous events for the vendor' do + query = described_class.new(vendor_id: vendor.id, section: 'previous', start_from_date: start_from_date) + + expect(query.events).to contain_exactly(previous_taxon) + end + end + + context 'when start_from_date is not provided' do + it 'defaults to the current time' do + travel_to(Time.zone.now) do + query = described_class.new(vendor_id: vendor.id, section: 'upcoming') + + expect(query.start_from_date.to_i).to be_within(1).of(Time.zone.now.to_i) + end + end + end + + context 'when section is all' do + it 'returns all events for the vendor, both upcoming and previous' do + query = described_class.new(vendor_id: vendor.id, section: 'all', start_from_date: start_from_date) + + expect(query.events).to match_array([upcoming_taxon, previous_taxon]) + end + end + end +end diff --git a/spec/serializers/spree/v2/storefront/taxon_serializer_spec.rb b/spec/serializers/spree/v2/storefront/taxon_serializer_spec.rb index a211e159f..0f17d1e3a 100644 --- a/spec/serializers/spree/v2/storefront/taxon_serializer_spec.rb +++ b/spec/serializers/spree/v2/storefront/taxon_serializer_spec.rb @@ -50,7 +50,8 @@ :show_badge_status, :purchasable_on, :purchasable_on_app, - :purchasable_on_web + :purchasable_on_web, + :vendor_id ) end