xpost 0.1.4 → 0.1.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.DS_Store +0 -0
- data/.gitignore +1 -2
- data/.rspec +0 -0
- data/Gemfile +0 -0
- data/LICENSE +0 -0
- data/README.md +0 -0
- data/TODO.md +1 -28
- data/lib/xpost.rb +6 -8
- data/lib/xpost/authentication.rb +0 -5
- data/lib/xpost/configuration.rb +0 -15
- data/lib/xpost/models.rb +5 -0
- data/lib/xpost/models/address.rb +38 -0
- data/lib/xpost/models/item.rb +31 -0
- data/lib/xpost/models/order.rb +54 -0
- data/lib/xpost/orders.rb +16 -57
- data/lib/xpost/version.rb +1 -1
- data/spec/{order/address/address_spec.rb → address_spec.rb} +0 -0
- data/spec/factories/addresses.rb +28 -46
- data/spec/factories/items.rb +10 -10
- data/spec/factories/orders.rb +16 -39
- data/spec/helpers.rb +0 -0
- data/spec/{order/items/item_spec.rb → item_spec.rb} +5 -5
- data/spec/line_item_spec.rb +16 -0
- data/spec/orders/order_create_spec.rb +46 -0
- data/spec/orders/order_for_pickup_spec.rb +17 -0
- data/spec/orders/{find_spec.rb → orders_find_spec.rb} +2 -3
- data/spec/orders/{track_spec.rb → orders_track_spec.rb} +2 -2
- data/spec/spec_helper.rb +0 -1
- data/spec/xpost_spec.rb +0 -27
- data/xpost.gemspec +2 -6
- metadata +17 -68
- data/lib/.DS_Store +0 -0
- data/lib/xpost/.DS_Store +0 -0
- data/lib/xpost/address.rb +0 -77
- data/lib/xpost/item.rb +0 -44
- data/lib/xpost/order.rb +0 -135
- data/lib/xpost/statuses.rb +0 -29
- data/sample/sample_essential_order_details.json +0 -63
- data/sample/sample_xpost_order-confirmed.json +0 -317
- data/sample/sample_xpost_order-for-pickup.json +0 -379
- data/sample/sample_xpost_order-pending.json +0 -306
- data/sample/webhook_sample.json +0 -105
- data/spec/order/cancel_spec.rb +0 -37
- data/spec/order/confirm_spec.rb +0 -38
- data/spec/order/create_spec.rb +0 -97
- data/spec/order/for_pickup_spec.rb +0 -42
- data/spec/order/get_shipping_label_spec.rb +0 -60
- data/spec/order/order_spec.rb +0 -96
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: daeea5bd3cf6a8f61328026b19276b5775e590b3
|
4
|
+
data.tar.gz: 852c2e8c12ef2eceb7d87dc456d5a8f13aeb12c4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 84bf7d5da6a979326ddbe82bc78976542d8dba1fe834ad6b22740e3c38acf469f1f961eab491626ca6c1ac1633bcdd0f308aa3d9981049a136bc96c7cfff99d3
|
7
|
+
data.tar.gz: e09a5977510ea684ec0c51d0bf2b0a1a5a76712756305276f91d2d790cca8d93849776cb1a8fabe1bcd1419ff61cc68829b64616e7f597a4b6a602c2a54031cd
|
data/.DS_Store
CHANGED
File without changes
|
data/.gitignore
CHANGED
data/.rspec
CHANGED
File without changes
|
data/Gemfile
CHANGED
File without changes
|
data/LICENSE
CHANGED
File without changes
|
data/README.md
CHANGED
File without changes
|
data/TODO.md
CHANGED
@@ -1,32 +1,5 @@
|
|
1
1
|
|
2
|
-
# xpost To-Do's
|
3
|
-
|
4
|
-
- it should be able to track order statuses on Orders.all (???)
|
5
|
-
|
6
|
-
# Bonus To-Do's
|
7
2
|
|
8
|
-
|
9
|
-
- and error out if an @auth_token is missing from the config
|
10
|
-
- OR
|
11
|
-
- it should just generate auth_tokens all the time since the api_key + secret_keys should be present
|
12
|
-
- and it should make sure that any method call will error out if a config isnt present
|
13
|
-
|
14
|
-
- it should accept shopify order data
|
3
|
+
# xpost To-Do's
|
15
4
|
|
16
|
-
# xpost Done
|
17
5
|
|
18
|
-
- it returns the shipping labels for a single order
|
19
|
-
- it returns all the shipping labels for an array of tracking numbers (no need to check for for-pickup)
|
20
|
-
- link: orders/download/awb/zebra
|
21
|
-
- return S3 link of AWB (airwaybills)
|
22
|
-
- return S3 link of POD (proof of deliveries)
|
23
|
-
- it should be able to mark an order for_pickup
|
24
|
-
- it should be able to cancel an existing order
|
25
|
-
- it should view an existing order
|
26
|
-
- it should be able to confirm an existing order
|
27
|
-
- it should be able to create an order
|
28
|
-
- figure out line per line why the json file isn't reading the sub array
|
29
|
-
- Xpost::Order.to_json
|
30
|
-
- base details
|
31
|
-
- delivery address
|
32
|
-
- items
|
data/lib/xpost.rb
CHANGED
@@ -1,15 +1,13 @@
|
|
1
|
-
|
2
1
|
module Xpost
|
3
2
|
autoload :Configuration, 'xpost/configuration'
|
4
3
|
autoload :Authentication, 'xpost/authentication'
|
5
|
-
autoload :
|
4
|
+
autoload :Orders, 'xpost/orders'
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
autoload :Item, 'xpost/item'
|
6
|
+
module Models
|
7
|
+
autoload :Address, 'xpost/models/address'
|
8
|
+
autoload :Item, 'xpost/models/item'
|
9
|
+
autoload :Order, 'xpost/models/order'
|
10
|
+
end
|
13
11
|
|
14
12
|
class << self
|
15
13
|
attr_accessor :configuration
|
data/lib/xpost/authentication.rb
CHANGED
@@ -10,11 +10,6 @@ module Xpost
|
|
10
10
|
token = "#{header}.#{payload}.#{signature}"
|
11
11
|
end
|
12
12
|
|
13
|
-
def self.sample_auth_token
|
14
|
-
config = Xpost::Configuration.sample_configuration
|
15
|
-
Xpost::Authentication.authenticate(config.api_key, config.secret_key)
|
16
|
-
end
|
17
|
-
|
18
13
|
private
|
19
14
|
|
20
15
|
def self.header
|
data/lib/xpost/configuration.rb
CHANGED
@@ -8,20 +8,5 @@ module Xpost
|
|
8
8
|
@staging_url
|
9
9
|
@production_url
|
10
10
|
end
|
11
|
-
|
12
|
-
def self.sample_configuration
|
13
|
-
api_key_line = File.readlines('.env').first.chomp
|
14
|
-
secret_key_line = File.readlines('.env').last.chomp
|
15
|
-
api_key = api_key_line.split('=').last
|
16
|
-
secret_key = secret_key_line.split('=').last
|
17
|
-
|
18
|
-
sample_configuration = Xpost.configure do |config|
|
19
|
-
config.api_key = api_key
|
20
|
-
config.secret_key = secret_key
|
21
|
-
config.staging_url = "https://api.staging.lbcx.ph/v1"
|
22
|
-
config.production_url = "https://api.lbcx.ph/v1"
|
23
|
-
end
|
24
|
-
Xpost.configuration
|
25
|
-
end
|
26
11
|
end
|
27
12
|
end
|
data/lib/xpost/models.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'active_model'
|
2
|
+
require 'set'
|
3
|
+
|
4
|
+
module Xpost
|
5
|
+
module Models
|
6
|
+
class Address
|
7
|
+
include ActiveModel::Model
|
8
|
+
|
9
|
+
REQUIRED_ADDRESS_PARAMETERS = Set[:name, :shipment, :line_1, :city, :state, :postal_code, :country]
|
10
|
+
OPTIONAL_ADDRESS_PARAMETERS = Set[:company, :title, :email, :phone_number, :mobile_number, :fax_number,
|
11
|
+
:district, :line_2, :remarks]
|
12
|
+
|
13
|
+
attr_accessor :name, :shipment, :line_1, :city, :state, :postal_code, :country
|
14
|
+
attr_accessor :company, :title, :email, :phone_number, :mobile_number, :fax_number, :district, :line_2, :remarks
|
15
|
+
|
16
|
+
validates_presence_of :name, :shipment, :line_1, :city, :state, :postal_code, :country
|
17
|
+
|
18
|
+
def initialize(options = {})
|
19
|
+
@shipment = options[:shipment]
|
20
|
+
@name = options[:name]
|
21
|
+
@email = options[:email]
|
22
|
+
@phone_number = options[:phone_number]
|
23
|
+
@mobile_number = options[:mobile_number]
|
24
|
+
@fax_number = options[:fax_number]
|
25
|
+
@company = options[:company]
|
26
|
+
@title = options[:title]
|
27
|
+
@line_1 = options[:line_1]
|
28
|
+
@line_2 = options[:line_2]
|
29
|
+
@city = options[:city]
|
30
|
+
@district = options[:district]
|
31
|
+
@state = options[:state]
|
32
|
+
@postal_code = options[:postal_code]
|
33
|
+
@country = options[:country]
|
34
|
+
@remarks = options[:remarks]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'active_model'
|
2
|
+
require 'set'
|
3
|
+
|
4
|
+
module Xpost
|
5
|
+
module Models
|
6
|
+
class Item
|
7
|
+
include ActiveModel::Model
|
8
|
+
|
9
|
+
ITEM_TYPES = Set[:product, :shipping, :tax, :fee, :insurance, :discount]
|
10
|
+
|
11
|
+
attr_accessor :type, :description, :amount, :quantity, :metadata
|
12
|
+
|
13
|
+
validates_presence_of :type, :description, :amount
|
14
|
+
validate :check_item_type
|
15
|
+
|
16
|
+
def initialize(options = {})
|
17
|
+
@type = options[:type]
|
18
|
+
@description = options[:description]
|
19
|
+
@amount = options[:amount]
|
20
|
+
@quantity = options[:quantity]
|
21
|
+
@metadata = options[:metadata]
|
22
|
+
end
|
23
|
+
|
24
|
+
def check_item_type
|
25
|
+
if self.type.present? && !ITEM_TYPES.include?(self.type.to_sym)
|
26
|
+
errors.add(:type, "wrong item type")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'active_model'
|
2
|
+
require 'set'
|
3
|
+
|
4
|
+
module Xpost
|
5
|
+
module Models
|
6
|
+
class Order
|
7
|
+
include ActiveModel::Model
|
8
|
+
|
9
|
+
CONFIRMABLE_PARAMETERS = Set[:status, :email, :buyer_name, :contact_number, :delivery_address, :items,
|
10
|
+
:shipment, :total, :currency, :payment_method, :payment_provider]
|
11
|
+
FOR_PICKUP_PARAMETERS = Set[:pickup_address, :pickup_at]
|
12
|
+
|
13
|
+
attr_accessor :email, :buyer_name, :contact_number
|
14
|
+
attr_accessor :total, :currency, :payment_method, :payment_provider
|
15
|
+
attr_accessor :delivery_address, :pickup_address
|
16
|
+
attr_accessor :status, :items, :shipment
|
17
|
+
|
18
|
+
validates_presence_of :email, :buyer_name, :contact_number
|
19
|
+
validates_presence_of :delivery_address
|
20
|
+
|
21
|
+
def initialize(options = {})
|
22
|
+
@status = options[:status]
|
23
|
+
@email = options[:email]
|
24
|
+
@buyer_name = options[:buyer_name]
|
25
|
+
@contact_number = options[:contact_number]
|
26
|
+
@delivery_address = options[:delivery_address]
|
27
|
+
@items = options[:items]
|
28
|
+
@shipment = options[:shipment]
|
29
|
+
@total = options[:total]
|
30
|
+
@currency = options[:currency]
|
31
|
+
@payment_method = options[:payment_method]
|
32
|
+
@payment_provider = options[:payment_provider]
|
33
|
+
@pickup_address = options[:pickup_address]
|
34
|
+
@pickup_at = options[:pickup_at]
|
35
|
+
end
|
36
|
+
|
37
|
+
def confirmable?
|
38
|
+
self.valid? && self.delivery_address.present?
|
39
|
+
end
|
40
|
+
|
41
|
+
# https://docs.quadx.xyz/#5f38afd0-66bb-468f-ab4e-993d4745a257
|
42
|
+
# Sets the order status to canceled. An order can be canceled provided they have not passed the cutoff date and time as specified in the contract.
|
43
|
+
def cancellable?
|
44
|
+
true
|
45
|
+
end
|
46
|
+
|
47
|
+
# https://docs.quadx.xyz/#c831dc25-2de4-36c5-c321-8e9db0fc2105
|
48
|
+
# The following fields can be updated provided they have not passed the cutoff date and time as specified in the contract.
|
49
|
+
def updatable?
|
50
|
+
true
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/lib/xpost/orders.rb
CHANGED
@@ -6,28 +6,17 @@ require 'typhoeus'
|
|
6
6
|
# order = Order.create({...})
|
7
7
|
# order.confirm / order.cancel
|
8
8
|
# order.for_pickup(pickup_address, pickup_date)
|
9
|
+
# order.update({...})
|
9
10
|
|
10
11
|
module Xpost
|
11
12
|
class Orders
|
12
13
|
# cant actually get all orders since its paginated
|
13
|
-
def self.all(auth_token
|
14
|
-
|
15
|
-
"failed_pickup", "failed_delivery", "claimed",
|
16
|
-
"return_in_transit", "returned", "failed_return",
|
17
|
-
"out_for_delivery", "for_consolidation", "consolidated",
|
18
|
-
"for_dropoff", "dropped_off", "for_transfer", "for_acceptance",
|
19
|
-
"accepted", "canceled", "in_transit", "delivered"]
|
20
|
-
|
21
|
-
if valid_xpost_statuses.include?(status)
|
22
|
-
all_orders_url = "orders?status=#{status}"
|
23
|
-
else
|
24
|
-
all_orders_url = "orders"
|
25
|
-
end
|
14
|
+
def self.all(auth_token)
|
15
|
+
all_orders_url = "orders"
|
26
16
|
|
27
17
|
get_url(all_orders_url, headers: auth_header(auth_token))
|
28
18
|
end
|
29
19
|
|
30
|
-
# gets all the details of an order
|
31
20
|
def self.find(auth_token, tracking_number)
|
32
21
|
find_order_url = "orders/#{tracking_number}"
|
33
22
|
|
@@ -35,7 +24,6 @@ module Xpost
|
|
35
24
|
res = res[:message] == "Not Found" ? "Not Found" : res
|
36
25
|
end
|
37
26
|
|
38
|
-
# only gets the order tat (turnaround time) info
|
39
27
|
def self.track(auth_token, tracking_number)
|
40
28
|
track_order_url = "orders/#{tracking_number}"
|
41
29
|
|
@@ -43,66 +31,37 @@ module Xpost
|
|
43
31
|
res = res[:message] == "Not Found" ? "Not Found" : { timeline: res[:tat], events: res[:events] }
|
44
32
|
end
|
45
33
|
|
46
|
-
def self.
|
47
|
-
|
48
|
-
res = get_url(find_order_url, headers: auth_header(auth_token))
|
49
|
-
res[:status] != 404 && res[:message] != "Not Found"
|
50
|
-
end
|
51
|
-
|
52
|
-
def self.create(auth_token, order = nil, shipment = nil, reference_id = nil)
|
53
|
-
raise "Missing order data" if order.nil?
|
54
|
-
raise "Missing shipment data" if shipment.nil?
|
55
|
-
|
56
|
-
order.shipment = shipment
|
57
|
-
order.reference_id = reference_id
|
34
|
+
def self.create(auth_token, options = {})
|
35
|
+
raise "Missing order data" if options[:order_data].empty?
|
58
36
|
|
59
|
-
|
37
|
+
create_order_url = "orders"
|
38
|
+
order_data = options[:order_data]
|
39
|
+
|
40
|
+
res = post_url(create_order_url, data: order_data, headers: auth_header(auth_token))
|
60
41
|
end
|
61
42
|
|
62
|
-
def self.confirm(auth_token, tracking_number, payment_reference_id
|
63
|
-
# TODO: these checks are expensive (potentially three back and forth requests)
|
64
|
-
raise "Order not found" unless Xpost::Orders.exists?(auth_token, tracking_number)
|
65
|
-
raise "Order isn't pending" if Xpost::Orders.find(auth_token, tracking_number)[:status] != "pending"
|
66
|
-
|
43
|
+
def self.confirm(auth_token, tracking_number, payment_reference_id)
|
67
44
|
confirm_order_url = "orders/#{tracking_number}/confirm"
|
68
45
|
|
69
46
|
res = put_url(confirm_order_url, data: payment_reference_id, headers: auth_header(auth_token))
|
70
47
|
res = res[:message] == "Not Found" ? "Not Found" : res
|
71
48
|
end
|
72
49
|
|
73
|
-
def self.for_pickup(auth_token, tracking_number, pickup_address)
|
74
|
-
raise "Order isn't confirmed" if Xpost::Orders.find(auth_token, tracking_number)[:status] != "confirmed"
|
75
|
-
for_pickup_url = "orders/#{tracking_number}/for-pickup"
|
76
|
-
|
77
|
-
raise "Missing pickup address" if pickup_address.nil?
|
78
|
-
raise "Invalid pickup address" unless pickup_address.valid?
|
79
|
-
pickup_address = { pickup_address: pickup_address.attributes }
|
80
|
-
|
81
|
-
res = put_url(for_pickup_url, data: pickup_address, headers: auth_header(auth_token))
|
82
|
-
res = res[:message] == "Not Found" ? "Not Found" : res
|
83
|
-
end
|
84
|
-
|
85
50
|
def self.cancel(auth_token, tracking_number)
|
86
51
|
cancel_order_url = "orders/#{tracking_number}/cancel"
|
87
|
-
raise "Order isn't pending" if Xpost::Orders.find(auth_token, tracking_number)[:status] != "pending"
|
88
52
|
|
89
53
|
res = put_url(cancel_order_url, headers: auth_header(auth_token))
|
90
54
|
res = res[:message] == "Not Found" ? "Not Found" : res
|
91
55
|
end
|
92
56
|
|
93
|
-
def self.
|
94
|
-
|
95
|
-
|
57
|
+
def self.for_pickup(auth_token, tracking_number, pickup_address)
|
58
|
+
pickup_address = Xpost::Models::Address.new(pickup_address)
|
59
|
+
for_pickup_url = "orders/#{tracking_number}/for-pickup"
|
96
60
|
|
97
|
-
|
98
|
-
res = res[:message] == "Not Found" ? "Not Found" : res
|
99
|
-
else
|
100
|
-
raise "Order isn't for_pickup" if Xpost::Orders.find(auth_token, tracking_number)[:status] != "for_pickup"
|
101
|
-
shipping_label_url = "orders/#{tracking_number}/awb?type=zebra"
|
61
|
+
raise "Invalid address" unless pickup_address.valid?
|
102
62
|
|
103
|
-
|
104
|
-
|
105
|
-
end
|
63
|
+
res = put_url(for_pickup_url, data: pickup_address, headers: auth_header(auth_token))
|
64
|
+
res = res[:message] == "Not Found" ? "Not Found" : res
|
106
65
|
end
|
107
66
|
|
108
67
|
private
|
data/lib/xpost/version.rb
CHANGED
File without changes
|
data/spec/factories/addresses.rb
CHANGED
@@ -1,56 +1,38 @@
|
|
1
1
|
FactoryBot.define do
|
2
|
-
factory :address, class: Xpost::Address do
|
3
|
-
name
|
4
|
-
line_1
|
2
|
+
factory :address, class: Xpost::Models::Address do
|
3
|
+
name "Bobby Axelrod"
|
4
|
+
line_1 "Axe Capital"
|
5
5
|
end
|
6
6
|
|
7
|
-
factory :required_address, class: Xpost::Address do
|
8
|
-
name
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
7
|
+
factory :required_address, class: Xpost::Models::Address do
|
8
|
+
name "Bobby Axelrod"
|
9
|
+
shipment "small-pouch"
|
10
|
+
line_1 "855 Sixth Avenue"
|
11
|
+
city "New York"
|
12
|
+
state "NY"
|
13
|
+
postal_code 10001
|
14
|
+
country "US"
|
14
15
|
|
15
16
|
initialize_with { new(attributes) }
|
16
17
|
end
|
17
18
|
|
18
|
-
factory :complete_address, class: Xpost::Address do
|
19
|
-
name
|
20
|
-
|
21
|
-
|
22
|
-
city
|
23
|
-
state
|
24
|
-
postal_code
|
25
|
-
country
|
26
|
-
company
|
27
|
-
title
|
28
|
-
email
|
29
|
-
phone_number
|
30
|
-
mobile_number
|
31
|
-
fax_number
|
32
|
-
district
|
33
|
-
|
34
|
-
|
35
|
-
initialize_with { new(attributes) }
|
36
|
-
end
|
37
|
-
|
38
|
-
factory :complete_address_pickup, class: Xpost::Address do
|
39
|
-
name { "Taylor Mason" }
|
40
|
-
line_1 { "BGC Corporate Centre" }
|
41
|
-
line_2 { "7th floor" }
|
42
|
-
city { "Taguig" }
|
43
|
-
state { "Metro Manila" }
|
44
|
-
postal_code { "1634" }
|
45
|
-
country { "PH" }
|
46
|
-
company { "Taylor Mason Capital" }
|
47
|
-
title { "CEO" }
|
48
|
-
email { "taylor@tmcapital.com" }
|
49
|
-
phone_number { "12345678" }
|
50
|
-
mobile_number { "091712345678" }
|
51
|
-
fax_number { "12345678" }
|
52
|
-
district { "BGC" }
|
53
|
-
remarks { "" }
|
19
|
+
factory :complete_address, class: Xpost::Models::Address do
|
20
|
+
name "Bobby Axelrod"
|
21
|
+
shipment "small-pouch"
|
22
|
+
line_1 "855 Sixth Avenue"
|
23
|
+
city "New York"
|
24
|
+
state "NY"
|
25
|
+
postal_code 10001
|
26
|
+
country "US"
|
27
|
+
company "Axe Capital"
|
28
|
+
title "CEO"
|
29
|
+
email "bobby@axe.com"
|
30
|
+
phone_number "12345678"
|
31
|
+
mobile_number "091712345678"
|
32
|
+
fax_number "12345678"
|
33
|
+
district "Manhattan"
|
34
|
+
line_2 "5th floor"
|
35
|
+
remarks "Send ASAP"
|
54
36
|
|
55
37
|
initialize_with { new(attributes) }
|
56
38
|
end
|