Skip to content

Commit

Permalink
close #2112 create job when add to cart
Browse files Browse the repository at this point in the history
  • Loading branch information
panhachom committed Dec 9, 2024
1 parent 2f1ad7f commit 0001971
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
require 'google/cloud/firestore'
module SpreeCmCommissioner
module Api
module V2
module Storefront
module CartControllerDecorator
def self.prepended(base)
base.before_action :ensure_cart_exist, only: :add_item
base.before_action :ensure_cart_exist, only: %i[add_item enqueue_add_item]
base.before_action :ensure_valid_metadata, only: %i[create add_item enqueue_add_item]
base.before_action :load_variant, only: %i[add_item enqueue_add_item]
end

# one usecase where this neccessary is when order.state is 'complete', but complated_at & payment_state is null,
Expand Down Expand Up @@ -41,6 +44,37 @@ def ensure_cart_exist

@spree_current_order ||= create_service.call(create_cart_params).value
end

def enqueue_add_item
spree_authorize! :update, spree_current_order, order_token
spree_authorize! :show, @variant

job = SpreeCmCommissioner::Cart::AddItemJob.perform_later(
spree_current_order.id,
@variant.id,
add_item_params[:quantity],
add_item_params[:public_metadata],
add_item_params[:private_metadata],
add_item_params[:options]
)

SpreeCmCommissioner::Cart::AddItemStatusMarker.call(
order_number: spree_current_order.number,
job_id: job.job_id,
status: 'processing',
queued_at: Time.current
)

render json: { message: 'Item is being added to the cart' }, status: :ok
end

def firestore
@firestore ||= Google::Cloud::Firestore.new(project_id: service_account[:project_id], credentials: service_account)
end

def service_account
@service_account ||= Rails.application.credentials.cloud_firestore_service_account
end
end
end
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
module SpreeCmCommissioner
module Cart
class AddItemStatusMarker < BaseInteractor
delegate :order_number, :job_id, :status, :queued_at, :complete_at, to: :context

def call
if order_number.nil? || job_id.nil? || status.nil?
context.fail!(message: 'Missing required fields')
return
end

update_cart_firestore_status
end

def firestore
@firestore ||= Google::Cloud::Firestore.new(project_id: service_account[:project_id], credentials: service_account)
end

def service_account
@service_account ||= Rails.application.credentials.cloud_firestore_service_account
end

def update_cart_firestore_status
data_to_set = build_data_to_set

firestore.col('queues')
.doc('cart')
.col(order_number)
.doc(job_id)
.set(data_to_set, merge: true)
end

def build_data_to_set
{
status: status,
queued_at: queued_at.presence
}.compact
end
end
end
end
27 changes: 27 additions & 0 deletions app/jobs/spree_cm_commissioner/cart/add_item_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
require 'google/cloud/firestore'

module SpreeCmCommissioner
module Cart
class AddItemJob < ApplicationJob
def perform(order_id, variant_id, quantity, public_metadata, private_metadata, options) # rubocop:disable Metrics/ParameterLists
order = Spree::Order.find(order_id)
variant = Spree::Variant.find(variant_id)

Spree::Cart::AddItem.call(
order: order,
variant: variant,
quantity: quantity,
public_metadata: public_metadata,
private_metadata: private_metadata,
options: options
)

SpreeCmCommissioner::Cart::AddItemStatusMarker.call(
order_number: order.number,
job_id: job_id,
status: 'complete'
)
end
end
end
end
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@

resource :cart, controller: :cart, only: %i[show create destroy] do
patch :restart_checkout_flow
post :enqueue_add_item
end

resources :wished_items
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
require 'spec_helper'

RSpec.describe SpreeCmCommissioner::Cart::AddItemStatusMarker do
let(:order_number) { 'R12345678' }
let(:job_id) { 'job_456' }
let(:status) { 'processing' }
let(:queued_at) { Time.now }
let(:complete_at) { nil }

subject { described_class.new(order_number: order_number, job_id: job_id, status: status, queued_at: queued_at, complete_at: complete_at) }

describe '#call' do

it 'fails when order_number is missing' do
allow(subject).to receive(:order_number).and_return(nil)
expect { subject.call }.to raise_error(Interactor::Failure)
end

it 'fails when job_id is missing' do
allow(subject).to receive(:job_id).and_return(nil)
expect { subject.call }.to raise_error(Interactor::Failure)
end

it 'fails when status is missing' do
allow(subject).to receive(:status).and_return(nil)
expect { subject.call }.to raise_error(Interactor::Failure)
end

it 'calls update_cart_firestore_status' do
expect(subject).to receive(:update_cart_firestore_status)
subject.call
end
end
end
25 changes: 25 additions & 0 deletions spec/jobs/spree_cm_commissioner/add_item_job_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
require 'spec_helper'

RSpec.describe SpreeCmCommissioner::Cart::AddItemJob, type: :job do
describe '#perform' do
let(:order) { create(:order) }
let(:variant) { create(:variant) }
let(:quantity) { 2 }

it 'calls Spree::Cart::AddItem with correct arguments' do
add_item_service = instance_double(Spree::Cart::AddItem)
allow(Spree::Cart::AddItem).to receive(:new).and_return(add_item_service)
allow(add_item_service).to receive(:call).and_return(true)
described_class.new.perform(order.id, variant.id, quantity, {}, {}, {})

expect(add_item_service).to have_received(:call).with(
order: order,
variant: variant,
quantity: quantity,
public_metadata: {},
private_metadata: {},
options: {}
)
end
end
end

0 comments on commit 0001971

Please sign in to comment.