tradenity 0.1.0
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 +7 -0
- data/.gitignore +11 -0
- data/.rakeTasks +7 -0
- data/.rspec +2 -0
- data/.travis.yml +3 -0
- data/CHANGELOG.md +7 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +77 -0
- data/Rakefile +2 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/lib/tradenity/api.rb +12 -0
- data/lib/tradenity/error/exceptions.rb +48 -0
- data/lib/tradenity/error/message.rb +38 -0
- data/lib/tradenity/http/client.rb +122 -0
- data/lib/tradenity/model/base.rb +100 -0
- data/lib/tradenity/model/entities.rb +390 -0
- data/lib/tradenity/model/paging.rb +23 -0
- data/lib/tradenity/rails/railtie.rb +21 -0
- data/lib/tradenity/version.rb +3 -0
- data/lib/tradenity.rb +7 -0
- data/tradenity.gemspec +30 -0
- metadata +156 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5f045dc13c7fadc66ff394bde5206ad227e852ee
|
4
|
+
data.tar.gz: b7362d7bdb9709b93766da4069f07a35e6ab71e2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8bca31717e36191165244edb70f5fafb1725fe4d0bdf987593567a9842cacaf296169c9a0be11f6c18e0f2bb8881f118af23d4a6fe940681cb697575626a19a7
|
7
|
+
data.tar.gz: f223608b761b820461e01f4117607ffa9f1a5a72e474b9947b9386c678775055d45b79eb4ed4c98b91e8adba5f140ecf3031a77b8c8fea54335ff2a111b94e37
|
data/.gitignore
ADDED
data/.rakeTasks
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<Settings><!--This file was automatically generated by Ruby plugin.
|
3
|
+
You are allowed to:
|
4
|
+
1. Remove rake task
|
5
|
+
2. Add existing rake tasks
|
6
|
+
To add existing rake tasks automatically delete this file and reload the project.
|
7
|
+
--><RakeGroup description="" fullCmd="" taksId="rake"><RakeTask description="Build tradenity-0.1.0.gem into the pkg directory" fullCmd="build" taksId="build" /><RakeTask description="Build and install tradenity-0.1.0.gem into system gems" fullCmd="install" taksId="install" /><RakeTask description="Create tag v0.1.0 and build and push tradenity-0.1.0.gem to Rubygems" fullCmd="release" taksId="release" /><RakeGroup description="" fullCmd="" taksId="release"><RakeTask description="" fullCmd="release:guard_clean" taksId="guard_clean" /><RakeTask description="" fullCmd="release:rubygem_push" taksId="rubygem_push" /><RakeTask description="" fullCmd="release:source_control_push" taksId="source_control_push" /></RakeGroup></RakeGroup></Settings>
|
data/.rspec
ADDED
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 Joseph Fouad
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
Welcome to Ruby SDK for Tradenity ecommerce REST API
|
2
|
+
====================================================
|
3
|
+
|
4
|
+
|
5
|
+
## Prerequisites
|
6
|
+
|
7
|
+
To use the Tradenity SDK, you must have:
|
8
|
+
|
9
|
+
- Working Ruby development environment (currently v1.9.3 and v2.2.x are supported).
|
10
|
+
- Active account in [Tradenity](http://www.tradenity.com)
|
11
|
+
|
12
|
+
|
13
|
+
## Installation
|
14
|
+
|
15
|
+
You can install the Ruby SDK using the standard `gem` tool.
|
16
|
+
|
17
|
+
`gem install tradenity`
|
18
|
+
|
19
|
+
|
20
|
+
## Setup your credentials
|
21
|
+
|
22
|
+
First of all, you have to get API keys for your store, you can find it in your store `Edit` page.
|
23
|
+
To get there navigate to the stores list page, click on the `Edit` button next to your store name, scroll down till you find the `API Keys` section.
|
24
|
+
|
25
|
+
|
26
|
+
## Initialize the library
|
27
|
+
|
28
|
+
With the API key in hand, you can initialize the Tradenity client.
|
29
|
+
Tradenity client needs the API key and an instance of AuthTokenHolder
|
30
|
+
which is an object that makes Tradenity session integrates with the web framework's session mechanism.
|
31
|
+
The SDK provide implementation for Flask and Django. It's easy to implement your own for other frameworks, It is a simple 3 method interface.
|
32
|
+
|
33
|
+
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
|
37
|
+
require 'Tradenity'
|
38
|
+
|
39
|
+
Tradenity.api_key = 'sk_xxxxxxxxxxxxx'
|
40
|
+
|
41
|
+
```
|
42
|
+
Make sure to replace the api keys with the ones for your store, otherwise you will get authentication error
|
43
|
+
|
44
|
+
## Make your First call
|
45
|
+
|
46
|
+
The Tradenity SDK is organized into a group of model entitiy classes that corresponds to the REST API's resources, each encapsulate the operation for a specific entity model,
|
47
|
+
for example to perform operations related to the `Brand` resource you can use the corresponding `tradenity.sdk.entities.Brand` class.
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
Now, just call any method in your code.
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
|
55
|
+
@brand = Brand.find_by_id("1243-9786786-jhgjtu-789s6i")
|
56
|
+
|
57
|
+
```
|
58
|
+
|
59
|
+
|
60
|
+
## Tutorials and sample applications
|
61
|
+
|
62
|
+
We provide 2 sample applications, actually it is the same application implemented using 2 frameworks: `Rails`, and `Sinatra`.
|
63
|
+
|
64
|
+
[Camera store sample application live demo](http://camera-store-sample.tradenity.com/)
|
65
|
+
|
66
|
+
You can find the code at github:
|
67
|
+
|
68
|
+
[Camera store for rails code](https://github.com/tradenity/camerastore-ruby-rails-sample).
|
69
|
+
|
70
|
+
[Camera store for sinatra code](https://github.com/tradenity/camerastore-ruby-sinatra-sample).
|
71
|
+
|
72
|
+
We also provide a detailed explanation of the code of these sample applications in the form of a step by step tutorials:
|
73
|
+
|
74
|
+
[Camera store for rails tutorial](/kb/tutorials/ruby/rails).
|
75
|
+
|
76
|
+
[Camera store for sinatra tutorial](/kb/tutorials/ruby/sinatra).
|
77
|
+
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "tradenity"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
module Tradenity
|
2
|
+
|
3
|
+
class ClientErrorException < RuntimeError
|
4
|
+
|
5
|
+
end
|
6
|
+
|
7
|
+
class ServerErrorException < RuntimeError
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
class RequestErrorException < RuntimeError
|
12
|
+
def initialize(error)
|
13
|
+
super(error.message)
|
14
|
+
@error = error
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class AuthenticationException < RequestErrorException
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
class AuthorizationException < RequestErrorException
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
class EntityNotFoundException < RequestErrorException
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
class DataValidationException < RequestErrorException
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
class PaymentErrorException < RequestErrorException
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
class CustomerCreationException < RequestErrorException
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
class ShoppingCartException < RequestErrorException
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
class InventoryErrorException < RequestErrorException
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'virtus'
|
2
|
+
|
3
|
+
module Tradenity
|
4
|
+
|
5
|
+
UNAUTHORIZED_ERROR_CODE = 1001
|
6
|
+
ACCESS_DENIED_ERROR_CODE = 1002
|
7
|
+
|
8
|
+
METHOD_NOT_SUPPORTED_ERROR_CODE = 1102
|
9
|
+
|
10
|
+
NOT_FOUND_ERROR_CODE = 1201
|
11
|
+
DATA_VALIDATION_ERROR_CODE = 1203
|
12
|
+
|
13
|
+
INVALID_PAYMENT_ERROR_CODE = 1401
|
14
|
+
REFUND_ERROR_ERROR_CODE = 1402
|
15
|
+
GATEWAY_ERROR_ERROR_CODE = 1403
|
16
|
+
|
17
|
+
EXISTING_EMAIL_ERROR_CODE = 1601
|
18
|
+
EXISTING_USERNAME_ERROR_CODE = 1602
|
19
|
+
|
20
|
+
CART_INVALID_ITEM_ERROR_CODE = 1701
|
21
|
+
|
22
|
+
INVENTORY_INVALID_PRODUCT_ERROR_CODE = 1801
|
23
|
+
INVENTORY_NOT_AVAILABLE_PRODUCT_ERROR_CODE = 1802
|
24
|
+
|
25
|
+
class ErrorMessage
|
26
|
+
|
27
|
+
include Virtus.model
|
28
|
+
|
29
|
+
attribute :status, Integer
|
30
|
+
attribute :errorCode, Integer
|
31
|
+
attribute :error, String
|
32
|
+
attribute :timestamp, String
|
33
|
+
attribute :message, String
|
34
|
+
attribute :details, Hash
|
35
|
+
attribute :fieldErrors, Hash
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require 'unirest'
|
2
|
+
require 'tradenity/error/exceptions'
|
3
|
+
require 'tradenity/error/message'
|
4
|
+
|
5
|
+
module Tradenity
|
6
|
+
|
7
|
+
AUTH_TOKEN_HEADER_NAME = 'X-Tradenity-Session-ID'
|
8
|
+
AUTH_TOKEN_HEADER_SYMBOL = :x_tradenity_session_id
|
9
|
+
|
10
|
+
class HttpClient
|
11
|
+
@@instance = nil
|
12
|
+
|
13
|
+
def initialize()
|
14
|
+
@key = Tradenity.api_key
|
15
|
+
@current_session = nil
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
def self.get_instance
|
20
|
+
unless @@instance
|
21
|
+
@@instance = HttpClient.new
|
22
|
+
end
|
23
|
+
@@instance
|
24
|
+
end
|
25
|
+
|
26
|
+
def current_session(session)
|
27
|
+
@current_session = session
|
28
|
+
end
|
29
|
+
|
30
|
+
def auth_token
|
31
|
+
if @current_session.has_key? :auth_token
|
32
|
+
@current_session[:auth_token]
|
33
|
+
else
|
34
|
+
nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def http_op(op, url, data)
|
39
|
+
headers = {}
|
40
|
+
auth = nil
|
41
|
+
if auth_token == nil
|
42
|
+
auth = {:user=> @key, :password=> ''}
|
43
|
+
else
|
44
|
+
headers[AUTH_TOKEN_HEADER_NAME] = auth_token
|
45
|
+
end
|
46
|
+
begin
|
47
|
+
case op
|
48
|
+
when 'GET'
|
49
|
+
response = Unirest.get(url, headers: headers, auth: auth, parameters: data)
|
50
|
+
when 'POST'
|
51
|
+
response = Unirest.post(url, headers: headers, auth: auth, parameters: data)
|
52
|
+
when 'PUT'
|
53
|
+
response = Unirest.put(url, headers: headers, auth: auth, parameters: data)
|
54
|
+
when 'DELETE'
|
55
|
+
response = Unirest.delete(url, headers: headers, auth: auth, parameters: data)
|
56
|
+
else
|
57
|
+
raise 'You must provide a valid Http method.'
|
58
|
+
end
|
59
|
+
rescue
|
60
|
+
raise ClientErrorException.new
|
61
|
+
end
|
62
|
+
|
63
|
+
if response.headers.has_key? AUTH_TOKEN_HEADER_SYMBOL
|
64
|
+
|
65
|
+
@current_session[:auth_token] = response.headers[AUTH_TOKEN_HEADER_SYMBOL]
|
66
|
+
end
|
67
|
+
|
68
|
+
if response.code >= 400
|
69
|
+
translate_exception(response)
|
70
|
+
end
|
71
|
+
|
72
|
+
response.body
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
def get(url, data=nil)
|
77
|
+
http_op('GET', url, data)
|
78
|
+
end
|
79
|
+
|
80
|
+
def post(url, data=nil)
|
81
|
+
http_op('POST', url, data)
|
82
|
+
end
|
83
|
+
|
84
|
+
def put(url, data=nil)
|
85
|
+
http_op('PUT', url, data)
|
86
|
+
end
|
87
|
+
|
88
|
+
def delete( url)
|
89
|
+
http_op('DELETE', url, {})
|
90
|
+
end
|
91
|
+
|
92
|
+
def translate_exception(response)
|
93
|
+
error = ErrorMessage.new(response.body)
|
94
|
+
case response.code
|
95
|
+
when 500
|
96
|
+
raise ServerErrorException.new('API server error.')
|
97
|
+
when 401
|
98
|
+
raise AuthenticationException.new(error)
|
99
|
+
when 403
|
100
|
+
raise AuthorizationException.new(error)
|
101
|
+
when 404
|
102
|
+
raise EntityNotFoundException.new(error)
|
103
|
+
when 400
|
104
|
+
case error.errorCode
|
105
|
+
when DATA_VALIDATION_ERROR_CODE
|
106
|
+
raise DataValidationException.new(error)
|
107
|
+
when INVALID_PAYMENT_ERROR_CODE, GATEWAY_ERROR_ERROR_CODE, REFUND_ERROR_ERROR_CODE
|
108
|
+
raise PaymentErrorException.new(error)
|
109
|
+
when EXISTING_USERNAME_ERROR_CODE, EXISTING_EMAIL_ERROR_CODE
|
110
|
+
raise CustomerCreationException.new(error)
|
111
|
+
when CART_INVALID_ITEM_ERROR_CODE
|
112
|
+
raise ShoppingCartException.new(error)
|
113
|
+
when INVENTORY_INVALID_PRODUCT_ERROR_CODE, INVENTORY_NOT_AVAILABLE_PRODUCT_ERROR_CODE
|
114
|
+
raise InventoryErrorException.new(error)
|
115
|
+
else
|
116
|
+
raise RequestErrorException.new(error)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'tradenity/http/client'
|
2
|
+
|
3
|
+
module Tradenity
|
4
|
+
|
5
|
+
class IdentifiableResource
|
6
|
+
|
7
|
+
def id=(id)
|
8
|
+
@id = id
|
9
|
+
end
|
10
|
+
|
11
|
+
def id
|
12
|
+
if instance_variable_defined?('@id') && @id != nil
|
13
|
+
@id
|
14
|
+
elsif _links && _links.has_key?('self') && _links['self'].has_key?('href')
|
15
|
+
href = _links['self']['href']
|
16
|
+
@id = href.split('/')[-1]
|
17
|
+
@id
|
18
|
+
else
|
19
|
+
''
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
class BaseEntity < IdentifiableResource
|
26
|
+
|
27
|
+
def self.client
|
28
|
+
HttpClient.get_instance
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.resource_name
|
32
|
+
''
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.resource_base_path
|
36
|
+
"#{Tradenity.api_base}/#{resource_name}"
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.resource_path(resource_id)
|
40
|
+
"#{resource_base_path}/#{resource_id}"
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
def self.find_all(q={})
|
45
|
+
search(q)
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.find_one(q={})
|
49
|
+
search(q).first
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.find_by_id(id)
|
53
|
+
result = client.get(resource_path(id), {})
|
54
|
+
new(result)
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
|
59
|
+
def get_create_data
|
60
|
+
attributes
|
61
|
+
end
|
62
|
+
|
63
|
+
def get_update_data
|
64
|
+
attributes
|
65
|
+
end
|
66
|
+
|
67
|
+
def create
|
68
|
+
result = self.class.client.post(self.class.resource_base_path, get_create_data)
|
69
|
+
self.class.new(result)
|
70
|
+
end
|
71
|
+
|
72
|
+
def update
|
73
|
+
result = self.class.client.put(self.class.resource_path(id), get_update_data)
|
74
|
+
self.class.new(result)
|
75
|
+
end
|
76
|
+
|
77
|
+
def delete
|
78
|
+
self.class.client.delete(self.class.resource_path(id), {})
|
79
|
+
end
|
80
|
+
|
81
|
+
protected
|
82
|
+
def self.search(q={})
|
83
|
+
result = client.get(resource_base_path, q)
|
84
|
+
if result.has_key? '_embedded' # && result['_embedded'].has_key?(resource_name)
|
85
|
+
collection = result['_embedded'][resource_name]
|
86
|
+
page_info = result['page']
|
87
|
+
puts page_info
|
88
|
+
|
89
|
+
cats = collection.collect do |c|
|
90
|
+
new(c)
|
91
|
+
end
|
92
|
+
|
93
|
+
Page.new(cats, page_info['number'], page_info['size'])
|
94
|
+
else
|
95
|
+
Page.new([], 0, 0)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,390 @@
|
|
1
|
+
require 'virtus'
|
2
|
+
require 'bcrypt'
|
3
|
+
require 'tradenity/model/base'
|
4
|
+
|
5
|
+
module Tradenity
|
6
|
+
|
7
|
+
|
8
|
+
class Address < BaseEntity
|
9
|
+
include Virtus.model
|
10
|
+
|
11
|
+
def self.resource_name
|
12
|
+
'addresses'
|
13
|
+
end
|
14
|
+
|
15
|
+
attribute :streetLine1, String
|
16
|
+
attribute :streetLine2, String
|
17
|
+
attribute :city, String
|
18
|
+
attribute :state, String
|
19
|
+
attribute :zipCode, String
|
20
|
+
attribute :country, String
|
21
|
+
attribute :createdAt, DateTime
|
22
|
+
attribute :updatedAt, DateTime
|
23
|
+
attribute :_links, Hash
|
24
|
+
|
25
|
+
def to_hash(prefix=nil)
|
26
|
+
data = attributes.select {|key, value| [:streetLine1, :streetLine2, :city, :state, :zipCode, :country].include?(key) }
|
27
|
+
if prefix != nil
|
28
|
+
prefixed_data = {}
|
29
|
+
data.each do |key, value|
|
30
|
+
prefixed_data["#{prefix}#{key}"] = value
|
31
|
+
end
|
32
|
+
prefixed_data
|
33
|
+
else
|
34
|
+
data
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
class Brand < BaseEntity
|
42
|
+
include Virtus.model
|
43
|
+
|
44
|
+
def self.resource_name
|
45
|
+
'brands'
|
46
|
+
end
|
47
|
+
|
48
|
+
attribute :name, String
|
49
|
+
attribute :title, String
|
50
|
+
attribute :status, String
|
51
|
+
attribute :description, String
|
52
|
+
attribute :createdAt, DateTime
|
53
|
+
attribute :updatedAt, DateTime
|
54
|
+
attribute :_links, Hash
|
55
|
+
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
class Category < BaseEntity
|
61
|
+
include Virtus.model
|
62
|
+
|
63
|
+
def self.resource_name
|
64
|
+
'categories'
|
65
|
+
end
|
66
|
+
|
67
|
+
attribute :name, String
|
68
|
+
attribute :title, String
|
69
|
+
attribute :status, String
|
70
|
+
attribute :description, String
|
71
|
+
attribute :depth, Integer
|
72
|
+
attribute :position, Integer
|
73
|
+
attribute :createdAt, DateTime
|
74
|
+
attribute :updatedAt, DateTime
|
75
|
+
attribute :_links, Hash
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
class Currency < BaseEntity
|
80
|
+
include Virtus.model
|
81
|
+
|
82
|
+
def self.resource_name
|
83
|
+
'currencies'
|
84
|
+
end
|
85
|
+
|
86
|
+
attribute :code, String
|
87
|
+
attribute :title, String
|
88
|
+
attribute :status, String
|
89
|
+
attribute :exchangeRate, Float
|
90
|
+
attribute :createdAt, DateTime
|
91
|
+
attribute :updatedAt, DateTime
|
92
|
+
attribute :_links, Hash
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
class Customer < BaseEntity
|
98
|
+
include Virtus.model
|
99
|
+
|
100
|
+
def self.resource_name
|
101
|
+
'customers'
|
102
|
+
end
|
103
|
+
|
104
|
+
attribute :firstName, String
|
105
|
+
attribute :lastName, String
|
106
|
+
attribute :email, String
|
107
|
+
attribute :username, String
|
108
|
+
attribute :password, String
|
109
|
+
attribute :status, String
|
110
|
+
attribute :createdAt, DateTime
|
111
|
+
attribute :updatedAt, DateTime
|
112
|
+
attribute :_links, Hash
|
113
|
+
|
114
|
+
def self.find_by_username(username)
|
115
|
+
find_one(username: username)
|
116
|
+
end
|
117
|
+
|
118
|
+
def valid_password?(pass)
|
119
|
+
BCrypt::Password.new(password) == pass
|
120
|
+
end
|
121
|
+
|
122
|
+
def get_create_data
|
123
|
+
data = attributes.select {|key, value| [:firstName, :lastName, :email, :username, :password].include?(key) }
|
124
|
+
data[:status] = 'active'
|
125
|
+
data
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
|
131
|
+
class Gateway < BaseEntity
|
132
|
+
include Virtus.model
|
133
|
+
|
134
|
+
def self.resource_name
|
135
|
+
'gateways'
|
136
|
+
end
|
137
|
+
|
138
|
+
attribute :name, String
|
139
|
+
attribute :title, String
|
140
|
+
attribute :status, String
|
141
|
+
attribute :description, String
|
142
|
+
attribute :mode, String
|
143
|
+
attribute :accountId, String
|
144
|
+
attribute :secretKey, String
|
145
|
+
attribute :publicKey, String
|
146
|
+
attribute :testSecretKey, String
|
147
|
+
attribute :testPublicKey, String
|
148
|
+
attribute :createdAt, DateTime
|
149
|
+
attribute :updatedAt, DateTime
|
150
|
+
attribute :_links, Hash
|
151
|
+
|
152
|
+
end
|
153
|
+
|
154
|
+
|
155
|
+
class Photo
|
156
|
+
include Virtus.model
|
157
|
+
|
158
|
+
attribute :name, String
|
159
|
+
attribute :url, String
|
160
|
+
attribute :createdAt, DateTime
|
161
|
+
attribute :updatedAt, DateTime
|
162
|
+
end
|
163
|
+
|
164
|
+
class Dimensions
|
165
|
+
include Virtus.model
|
166
|
+
|
167
|
+
attribute :unit, String
|
168
|
+
attribute :width, Float
|
169
|
+
attribute :height, Float
|
170
|
+
attribute :depth, Float
|
171
|
+
end
|
172
|
+
|
173
|
+
class Weight
|
174
|
+
include Virtus.model
|
175
|
+
|
176
|
+
attribute :unit, String
|
177
|
+
attribute :amount, Float
|
178
|
+
end
|
179
|
+
|
180
|
+
class Product < BaseEntity
|
181
|
+
include Virtus.model
|
182
|
+
|
183
|
+
def self.resource_name
|
184
|
+
'products'
|
185
|
+
end
|
186
|
+
|
187
|
+
attribute :name, String
|
188
|
+
attribute :title, String
|
189
|
+
attribute :status, String
|
190
|
+
attribute :sku, String
|
191
|
+
attribute :description, String
|
192
|
+
attribute :shortDescription, String
|
193
|
+
attribute :fullDescription, String
|
194
|
+
attribute :specifications, String
|
195
|
+
attribute :stockLevel, Integer
|
196
|
+
attribute :minimumStockLevel, Integer
|
197
|
+
attribute :hasSellLimit, Boolean
|
198
|
+
attribute :maximumSellCount, Integer
|
199
|
+
attribute :stockStatus, String
|
200
|
+
attribute :price, Float
|
201
|
+
attribute :itemWeight, Weight
|
202
|
+
attribute :packageWeight, Weight
|
203
|
+
attribute :itemDimensions, Dimensions
|
204
|
+
attribute :packageDimensions, Dimensions
|
205
|
+
attribute :createdAt, DateTime
|
206
|
+
attribute :updatedAt, DateTime
|
207
|
+
attribute :mainPhoto, Photo
|
208
|
+
attribute :photos, Array[Photo]
|
209
|
+
attribute :_links, Hash
|
210
|
+
end
|
211
|
+
|
212
|
+
|
213
|
+
class Collection < BaseEntity
|
214
|
+
include Virtus.model
|
215
|
+
|
216
|
+
def self.resource_name
|
217
|
+
'collections'
|
218
|
+
end
|
219
|
+
|
220
|
+
attribute :name, String
|
221
|
+
attribute :title, String
|
222
|
+
attribute :status, String
|
223
|
+
attribute :description, String
|
224
|
+
attribute :createdAt, DateTime
|
225
|
+
attribute :updatedAt, DateTime
|
226
|
+
attribute :products, Array[Product]
|
227
|
+
attribute :_links, Hash
|
228
|
+
end
|
229
|
+
|
230
|
+
|
231
|
+
class LineItem < IdentifiableResource
|
232
|
+
include Virtus.model
|
233
|
+
|
234
|
+
attribute :quantity, Integer
|
235
|
+
attribute :unitPrice, Float
|
236
|
+
attribute :subtotal, Float
|
237
|
+
attribute :total, Float
|
238
|
+
attribute :taxes, Float
|
239
|
+
attribute :shippingCost, Float
|
240
|
+
attribute :product, Product
|
241
|
+
attribute :_links, Hash
|
242
|
+
|
243
|
+
end
|
244
|
+
|
245
|
+
class ShippingMethod < BaseEntity
|
246
|
+
include Virtus.model
|
247
|
+
|
248
|
+
def self.resource_name
|
249
|
+
'shippingMethods'
|
250
|
+
end
|
251
|
+
|
252
|
+
attribute :name, String
|
253
|
+
attribute :title, String
|
254
|
+
attribute :status, String
|
255
|
+
attribute :description, String
|
256
|
+
attribute :costType, String
|
257
|
+
attribute :fixedRate, Float
|
258
|
+
attribute :costPerUnitWeight, Float
|
259
|
+
attribute :weightUnit, String
|
260
|
+
attribute :_links, Hash
|
261
|
+
end
|
262
|
+
|
263
|
+
class ShippingOption
|
264
|
+
include Virtus.model
|
265
|
+
|
266
|
+
attribute :shippingMethod, ShippingMethod
|
267
|
+
attribute :cost, Float
|
268
|
+
attribute :orderTotal, Float
|
269
|
+
end
|
270
|
+
|
271
|
+
class ShoppingCart < BaseEntity
|
272
|
+
include Virtus.model
|
273
|
+
|
274
|
+
def self.resource_name
|
275
|
+
'shoppingCarts'
|
276
|
+
end
|
277
|
+
|
278
|
+
attribute :total, Float
|
279
|
+
attribute :subtotal, Float
|
280
|
+
attribute :count, Integer
|
281
|
+
attribute :items, Array[LineItem]
|
282
|
+
attribute :_links, Hash
|
283
|
+
|
284
|
+
def self.get
|
285
|
+
new(client.get(resource_base_path))
|
286
|
+
end
|
287
|
+
|
288
|
+
def self.add(item)
|
289
|
+
new(client.post(resource_base_path, {product: item.product.id, quantity: item.quantity}))
|
290
|
+
end
|
291
|
+
|
292
|
+
def self.remove(item_id)
|
293
|
+
new(client.delete("#{resource_base_path}/#{item_id}"))
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
class Checkout
|
298
|
+
include Virtus.model
|
299
|
+
|
300
|
+
attribute :subtotal, Float
|
301
|
+
attribute :total, Float
|
302
|
+
attribute :taxes, Float
|
303
|
+
attribute :items, Array[LineItem]
|
304
|
+
attribute :shippingOptions, Array[ShippingOption]
|
305
|
+
attribute :currency, Currency
|
306
|
+
attribute :gateway, Gateway
|
307
|
+
end
|
308
|
+
|
309
|
+
class Order < BaseEntity
|
310
|
+
include Virtus.model
|
311
|
+
|
312
|
+
def self.resource_name
|
313
|
+
'orders'
|
314
|
+
end
|
315
|
+
|
316
|
+
attribute :count, Integer
|
317
|
+
attribute :total, Float
|
318
|
+
attribute :subtotal, Float
|
319
|
+
attribute :shippingCost, Float
|
320
|
+
attribute :items, Array[LineItem]
|
321
|
+
attribute :customer, Customer
|
322
|
+
attribute :billingAddress, Address
|
323
|
+
attribute :shippingAddress, Address
|
324
|
+
attribute :status, String
|
325
|
+
attribute :createdAt, DateTime
|
326
|
+
attribute :updatedAt, DateTime
|
327
|
+
attribute :purchasedAt, DateTime
|
328
|
+
attribute :completedAt, DateTime
|
329
|
+
attribute :_links, Hash
|
330
|
+
|
331
|
+
def self.find_all_by_customer(customer_id)
|
332
|
+
find_all(customer: customer_id)
|
333
|
+
end
|
334
|
+
|
335
|
+
def get_checkout_data
|
336
|
+
data = {customer: customer.id}
|
337
|
+
data.merge!(billingAddress.to_hash('billingAddress.'))
|
338
|
+
data.merge!(shippingAddress.to_hash('shippingAddress.'))
|
339
|
+
data
|
340
|
+
end
|
341
|
+
|
342
|
+
def checkout(payment_source)
|
343
|
+
data = get_checkout_data
|
344
|
+
data['paymentSource'] = payment_source
|
345
|
+
result = self.class.client.post(self.class.resource_base_path, data)
|
346
|
+
Transaction.new(result)
|
347
|
+
end
|
348
|
+
|
349
|
+
def self.refund(order_id)
|
350
|
+
result = client.put("#{resource_base_path}/#{order_id}/refund", data={})
|
351
|
+
Transaction.new(result)
|
352
|
+
end
|
353
|
+
|
354
|
+
end
|
355
|
+
|
356
|
+
class Tax < BaseEntity
|
357
|
+
include Virtus.model
|
358
|
+
|
359
|
+
def self.resource_name
|
360
|
+
'taxes'
|
361
|
+
end
|
362
|
+
|
363
|
+
attribute :name, String
|
364
|
+
attribute :title, String
|
365
|
+
attribute :status, String
|
366
|
+
attribute :description, String
|
367
|
+
attribute :createdAt, DateTime
|
368
|
+
attribute :updatedAt, DateTime
|
369
|
+
attribute :_links, Hash
|
370
|
+
|
371
|
+
end
|
372
|
+
|
373
|
+
|
374
|
+
class Transaction < BaseEntity
|
375
|
+
include Virtus.model
|
376
|
+
|
377
|
+
def self.resource_name
|
378
|
+
'transactions'
|
379
|
+
end
|
380
|
+
|
381
|
+
attribute :type, String
|
382
|
+
attribute :status, String
|
383
|
+
attribute :gatewayOperationId, String
|
384
|
+
attribute :order, Order
|
385
|
+
attribute :gateway, Gateway
|
386
|
+
attribute :createdAt, DateTime
|
387
|
+
attribute :updatedAt, DateTime
|
388
|
+
attribute :_links, Hash
|
389
|
+
end
|
390
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Tradenity
|
2
|
+
|
3
|
+
class Page < Array
|
4
|
+
def initialize(content=[], page=0, size=0)
|
5
|
+
concat(content)
|
6
|
+
@page_number = page
|
7
|
+
@page_size = size
|
8
|
+
end
|
9
|
+
|
10
|
+
def is_empty?
|
11
|
+
@page_size <= 0
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
class PageRequest
|
17
|
+
def initialize(page, size)
|
18
|
+
@page_number = page
|
19
|
+
@page_size = size
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Tradenity
|
2
|
+
module RailsSupport
|
3
|
+
def adjust_tradenity_session
|
4
|
+
HttpClient.get_instance.current_session(session)
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
class Railtie < ::Rails::Railtie
|
9
|
+
initializer 'tradenity.configure_controllers' do |app|
|
10
|
+
|
11
|
+
ActiveSupport.on_load :action_controller do
|
12
|
+
|
13
|
+
include Tradenity
|
14
|
+
include Tradenity::RailsSupport
|
15
|
+
|
16
|
+
before_filter :adjust_tradenity_session
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/tradenity.rb
ADDED
data/tradenity.gemspec
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'tradenity/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "tradenity"
|
8
|
+
spec.version = Tradenity::VERSION
|
9
|
+
spec.authors = ["Joseph Fouad"]
|
10
|
+
spec.email = ["tradenity@tradenity.com"]
|
11
|
+
|
12
|
+
|
13
|
+
|
14
|
+
spec.summary = %q{Access Tradenity eCommerce API.}
|
15
|
+
spec.description = %q{Client library for easy develop against Tradenity eCommerce REST API.}
|
16
|
+
spec.homepage = "http://githun.com/tradenity/ruby-sdk"
|
17
|
+
spec.license = "Apache-2.0"
|
18
|
+
|
19
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
20
|
+
spec.bindir = "bin"
|
21
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
22
|
+
spec.require_paths = ["lib"]
|
23
|
+
|
24
|
+
spec.add_runtime_dependency 'virtus', '~> 1.0', '>= 1.0.5'
|
25
|
+
spec.add_runtime_dependency 'unirest', '~> 1.1', '>= 1.1.2'
|
26
|
+
spec.add_runtime_dependency 'bcrypt', '~> 3.1', '>= 3.1.1'
|
27
|
+
|
28
|
+
spec.add_development_dependency "bundler", "~> 1.8"
|
29
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
30
|
+
end
|
metadata
ADDED
@@ -0,0 +1,156 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tradenity
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Joseph Fouad
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-10-29 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: virtus
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.0'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.0.5
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.0'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.0.5
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: unirest
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '1.1'
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 1.1.2
|
43
|
+
type: :runtime
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '1.1'
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 1.1.2
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: bcrypt
|
55
|
+
requirement: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - "~>"
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '3.1'
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 3.1.1
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '3.1'
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 3.1.1
|
73
|
+
- !ruby/object:Gem::Dependency
|
74
|
+
name: bundler
|
75
|
+
requirement: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - "~>"
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '1.8'
|
80
|
+
type: :development
|
81
|
+
prerelease: false
|
82
|
+
version_requirements: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - "~>"
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '1.8'
|
87
|
+
- !ruby/object:Gem::Dependency
|
88
|
+
name: rake
|
89
|
+
requirement: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - "~>"
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '10.0'
|
94
|
+
type: :development
|
95
|
+
prerelease: false
|
96
|
+
version_requirements: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - "~>"
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '10.0'
|
101
|
+
description: Client library for easy develop against Tradenity eCommerce REST API.
|
102
|
+
email:
|
103
|
+
- tradenity@tradenity.com
|
104
|
+
executables:
|
105
|
+
- console
|
106
|
+
- setup
|
107
|
+
extensions: []
|
108
|
+
extra_rdoc_files: []
|
109
|
+
files:
|
110
|
+
- ".gitignore"
|
111
|
+
- ".rakeTasks"
|
112
|
+
- ".rspec"
|
113
|
+
- ".travis.yml"
|
114
|
+
- CHANGELOG.md
|
115
|
+
- Gemfile
|
116
|
+
- LICENSE.txt
|
117
|
+
- README.md
|
118
|
+
- Rakefile
|
119
|
+
- bin/console
|
120
|
+
- bin/setup
|
121
|
+
- lib/tradenity.rb
|
122
|
+
- lib/tradenity/api.rb
|
123
|
+
- lib/tradenity/error/exceptions.rb
|
124
|
+
- lib/tradenity/error/message.rb
|
125
|
+
- lib/tradenity/http/client.rb
|
126
|
+
- lib/tradenity/model/base.rb
|
127
|
+
- lib/tradenity/model/entities.rb
|
128
|
+
- lib/tradenity/model/paging.rb
|
129
|
+
- lib/tradenity/rails/railtie.rb
|
130
|
+
- lib/tradenity/version.rb
|
131
|
+
- tradenity.gemspec
|
132
|
+
homepage: http://githun.com/tradenity/ruby-sdk
|
133
|
+
licenses:
|
134
|
+
- Apache-2.0
|
135
|
+
metadata: {}
|
136
|
+
post_install_message:
|
137
|
+
rdoc_options: []
|
138
|
+
require_paths:
|
139
|
+
- lib
|
140
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
146
|
+
requirements:
|
147
|
+
- - ">="
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
requirements: []
|
151
|
+
rubyforge_project:
|
152
|
+
rubygems_version: 2.6.7
|
153
|
+
signing_key:
|
154
|
+
specification_version: 4
|
155
|
+
summary: Access Tradenity eCommerce API.
|
156
|
+
test_files: []
|