-
Notifications
You must be signed in to change notification settings - Fork 9
GCW-3407 Gogox Gem Integration and Transport APIs #1195
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
a20b5fb
aadd4af
95d857a
16bd4e5
f8d67e1
b07afd7
2836828
3bfc95a
f25a776
39ab917
54a32fd
a50cbfe
40c6d28
ec9d674
45c4788
b9af1db
ea321a2
0b3166f
e1d3860
3835482
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
GIT | ||
remote: [email protected]:crossroads/go_go_van_api.git | ||
revision: 3cbc5590e2a11a7903483de276bc668be88843cb | ||
revision: e860edbdc14f67b02139cba678fd7d2a68f5f591 | ||
branch: master | ||
specs: | ||
go_go_van_api (0.0.1) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
module Api | ||
module V1 | ||
class TransportsController < Api::V1::ApiController | ||
|
||
skip_authorization_check only: :update_hook | ||
load_and_authorize_resource :transport_order, parent: false, except: [:update_hook] | ||
|
||
before_action :validate_transport_source, only: [:quote, :book] | ||
|
||
api :GET, '/v1/transports/providers', "List all GoodCity Tranports Options." | ||
def providers | ||
render json: TransportProvider.all.cached_json | ||
end | ||
|
||
api :POST, '/v1/transports/quote', "Get provider quote" | ||
param :provider, TRANSPORT_PROVIDERS, required: true, desc: "Provider selected for transport" | ||
param :vehicle_type, String, required: true, desc: "Transport vehicle-type" | ||
param :source_id, [Integer, String], required: true, desc: "Id of the source (offer/order)" | ||
param :source_type, String, required: true, desc: "Type of the source (offer/order)" | ||
param :schedule_at, String, desc: "Scheduled time for delivery" | ||
param :district_id, String, desc: "Id of the district" | ||
def quote | ||
order_price = TransportService.new(transport_params.to_h).quotation | ||
render json: order_price | ||
end | ||
|
||
api :POST, '/v1/transports/book', "Book transport" | ||
param :provider, TRANSPORT_PROVIDERS, required: true, desc: "Provider selected for transport" | ||
param :vehicle_type, String, required: true, desc: "Transport vehicle-type" | ||
param :source_id, String, required: true, desc: "Id of the source (offer/order)" | ||
param :source_type, String, required: true, desc: "Type of the source (offer/order)" | ||
param :schedule_at, String, required: true, desc: "Scheduled time for delivery" | ||
param :district_id, String, desc: "Id of the district" | ||
param :pickup_contact_name, String, desc: "Contact Person Name" | ||
param :pickup_contact_phone, String, desc: "Contact Person Mobile" | ||
param :pickup_street_address, String, required: true, desc: "Pickup Address" | ||
def book | ||
order_info = TransportService.new(transport_params.to_h).book | ||
swatijadhav marked this conversation as resolved.
Show resolved
Hide resolved
|
||
render json: order_info | ||
end | ||
|
||
api :GET, '/v1/transports/:order_uuid', "Get GoodCity Tranport order details." | ||
def show | ||
order_info = TransportService.new({booking_id: params[:order_uuid], provider: transport_provider}).status | ||
render json: order_info | ||
end | ||
|
||
api :POST, '/v1/transports/:order_uuid/cancel', "Cancel GoodCity Tranport order." | ||
def cancel | ||
order_info = TransportService.new({booking_id: params[:order_uuid], provider: transport_provider}).cancel | ||
render json: order_info | ||
end | ||
|
||
api :POST, '/v1/transports/update_hook', "Webhook to update transport status" | ||
def update_hook | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When implemented, we should use our own authorization check here. E.g. webhook can be Then check |
||
# setup ngrok and inspect response | ||
# response details are not yet available from Gogox Provider | ||
end | ||
|
||
private | ||
|
||
def validate_transport_source | ||
if params['source_type'] == 'Offer' | ||
if !User.current_user.offers.pluck(:id).include?(params['source_id'].to_i) | ||
raise Goodcity::UnauthorizedError.with_text("You are not authorized to book transport for this offer.") | ||
end | ||
end | ||
|
||
if params['source_type'] == 'Order' | ||
if !User.current_user.created_orders.pluck(:id).include?(params['source_id'].to_i) | ||
raise Goodcity::UnauthorizedError.with_text("You are not authorized to book transport for this order.") | ||
end | ||
end | ||
end | ||
|
||
def transport_provider | ||
order = TransportOrder.find_by(order_uuid: params[:order_uuid]) | ||
order.try(:transport_provider).try(:name) | ||
end | ||
|
||
def transport_params | ||
set_district_id unless params["district_id"].presence | ||
params.permit([ | ||
"schedule_at", "district_id", "provider", "vehicle_type", | ||
"pickup_street_address", "pickup_contact_name", "pickup_contact_phone", | ||
"source_type", "source_id" | ||
]) | ||
end | ||
|
||
def set_district_id | ||
params["district_id"] = User.current_user.address.district_id | ||
end | ||
|
||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
class TransportOrder < ApplicationRecord | ||
belongs_to :transport_provider | ||
belongs_to :source, polymorphic: true | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
class TransportProvider < ApplicationRecord | ||
include CacheableJson | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module Api::V1 | ||
class TransportProviderSerializer < ApplicationSerializer | ||
attributes :id, :name, :logo, :description, :metadata | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
class Gogox | ||
swatijadhav marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
attr_accessor :params, :time, :vehicle | ||
|
||
VEHICLE_TYPES = ["van", "mudou", "mudou9"] | ||
|
||
def initialize(options = {}) | ||
@params = options | ||
@time = parse_pickup_time(options[:schedule_at]) | ||
@vehicle = options[:vehicle_type] | ||
end | ||
|
||
# Rsponse | ||
# { | ||
# "uuid" => "2f859363-5c43-4fe2-9b91-6c6c43d610d2", | ||
# "status" => "pending", | ||
# "vehicle_type" => "van", | ||
# "payment_method" => "prepaid_wallet", | ||
# "courier" => {}, | ||
# "pickup" => { | ||
# "name" => "Swati J", | ||
# "street_address" => "123", | ||
# "floor_or_unit_number" => nil, | ||
# "schedule_at" => 1609242940, | ||
# "location" => {"lat" => 22.5029632, "lng" => 114.1277213}, | ||
# "contact" => { | ||
# "name" => "Swati J", | ||
# "phone_number" => "51111113", | ||
# "phone_extension" => nil | ||
# } | ||
# }, | ||
# "destinations" => [{ | ||
# "name" => "GCAdmin User", | ||
# "street_address" => "Santa Peak Road", | ||
# "floor_or_unit_number" => nil, | ||
# "location" => {"lat" => 32.3700365, "lng" => 120.9930016}, | ||
# "contact" => { | ||
# "name" => "GCAdmin User", | ||
# "phone_number" => "51111111" | ||
# } | ||
# }], | ||
# "note_to_courier" => nil, | ||
# "price" => {"amount" => 15000, "currency" => "HKD"}, | ||
# "price_breakdown" => [{"key" => "fee", "amount" => 15000}] | ||
# } | ||
def book | ||
GogoxApi::Transport.new(order_attributes).order | ||
end | ||
|
||
# Response: | ||
# { | ||
# "vehicle_type" => "van", | ||
# "estimated_price" => {"amount" => 15000, "currency" => "HKD"}, | ||
# "estimated_price_breakdown" => [{"key" => "fee", "amount" => 15000}] | ||
# } | ||
def quotation | ||
GogoxApi::Transport.new(quotation_attributes).quotation | ||
end | ||
|
||
class << self | ||
|
||
def transport_status(booking_id) | ||
GogoxApi::Transport.new.status(booking_id) | ||
end | ||
|
||
# Response | ||
# Response is nil on successful cancellation of GOGOX transport | ||
def cancel_order(booking_id) | ||
response = GogoxApi::Transport.new.cancel(booking_id) | ||
if !response | ||
{ | ||
order_uuid: booking_id, | ||
status: "cancelled" | ||
} | ||
end | ||
end | ||
|
||
end | ||
|
||
private | ||
|
||
def order_attributes | ||
{ | ||
'vehicle_type': vehicle_type, | ||
"pickup_location": params[:pickup_location], | ||
"pickup_street_address": params[:pickup_street_address], | ||
"schedule_at": parse_time, | ||
"pickup_contact_name": params[:pickup_contact_name], | ||
"pickup_contact_phone": params[:pickup_contact_phone], | ||
"destination_location": params[:destination_location], | ||
"destination_street_address": params[:destination_street_address], | ||
"destination_contact_name": params[:destination_contact_name], | ||
"destination_contact_phone": params[:destination_contact_phone] | ||
} | ||
end | ||
|
||
def quotation_attributes | ||
{ | ||
'vehicle_type': vehicle_type, | ||
"schedule_at": parse_time, | ||
"pickup_location": params[:pickup_location], | ||
"destination_location": params[:destination_location] | ||
} | ||
end | ||
|
||
def vehicle_type | ||
if vehicle.blank? || !VEHICLE_TYPES.include?(vehicle) | ||
raise(ValueError, "vehicle should be from #{VEHICLE_TYPES.join(', ')}") | ||
end | ||
vehicle | ||
end | ||
|
||
def parse_pickup_time(time = nil) | ||
return time if time.present? | ||
|
||
# next available date within next 5 days | ||
next_available_date = DateSet.new(5, 1).available_dates.first | ||
(next_available_date.beginning_of_day + 12.hours) | ||
end | ||
|
||
def parse_time | ||
@time = DateTime.parse(@time.to_s) | ||
@time = @time.zone == "HKT" ? @time : @time.in_time_zone("Asia/Hong_Kong") | ||
@time.to_i | ||
end | ||
|
||
class ValueError < StandardError; end | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of just value error defining here, create a error in errors.rb |
||
end |
Uh oh!
There was an error while loading. Please reload this page.