stock_shaker 0.3.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.rspec +3 -0
- data/.rubocop.yml +53 -0
- data/.travis.yml +9 -0
- data/CHANGELOG.md +47 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +21 -0
- data/README.md +263 -0
- data/Rakefile +7 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/stock_shaker.rb +18 -0
- data/lib/stock_shaker/client/constants.rb +23 -0
- data/lib/stock_shaker/client/jd_central_op.rb +72 -0
- data/lib/stock_shaker/client/lazada_op.rb +116 -0
- data/lib/stock_shaker/client/shopee_op.rb +73 -0
- data/lib/stock_shaker/concern/utility.rb +18 -0
- data/lib/stock_shaker/config.rb +26 -0
- data/lib/stock_shaker/config/lazada_config.rb +15 -0
- data/lib/stock_shaker/config/shopee_config.rb +15 -0
- data/lib/stock_shaker/date_util.rb +15 -0
- data/lib/stock_shaker/request/jd_central_op.rb +40 -0
- data/lib/stock_shaker/request/lazada_op.rb +35 -0
- data/lib/stock_shaker/request/shopee_op.rb +34 -0
- data/lib/stock_shaker/version.rb +6 -0
- data/media/badge/lazada/generate_access_token.svg +1 -0
- data/media/badge/lazada/get_orders-get-green.svg +1 -0
- data/media/badge/lazada/lazada_api-order--api-yellow.svg +1 -0
- data/media/badge/lazada/lazada_api-system--api-yellow.svg +1 -0
- data/media/badge/lazada/refresh_access_token.svg +1 -0
- data/media/badge/made_with-shield_io-green.svg +1 -0
- data/media/badge/market_place_support/love-lazada-sky-blue.svg +1 -0
- data/media/badge/market_place_support/love-shopee-orange.svg +1 -0
- data/media/badge/shopee/get_orders_list-post-green.svg +1 -0
- data/media/badge/shopee/shopee_api-order--api-yellow.svg +1 -0
- data/media/badge/stock_shaker-new-orange.svg +1 -0
- data/media/icon.png +0 -0
- data/stock_shaker.gemspec +46 -0
- metadata +161 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 8ce3b6719c4b592c6a1d9756bc5bf8b6af2a67d28254e20d65788c345adf58f4
|
4
|
+
data.tar.gz: 99d5b98a57cb2355de108120850c359911084b803a792417bcc50be54e17c7e6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0ae4f8a29179046e7204961018f5637373852b37315f81d5109c4858afe7c2a7e11f320227bcb7c52839f99f233b40eee6d615dcf2edcc37c978b5168e563672
|
7
|
+
data.tar.gz: 0fb6fec3588c364d85c1c8f02b194a5e1b2dc7c7d4a631bdc6dfb304c18c0e8074dd85b0fa49a6298e4d66d9df29a3d1d4cc2d4c3bb01ada71051c1e1c3ff7ee
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: '2.3'
|
3
|
+
|
4
|
+
Metrics/BlockLength:
|
5
|
+
Exclude:
|
6
|
+
- 'stock_shaker.gemspec'
|
7
|
+
|
8
|
+
# Commonly used screens these days easily fit more than 80 characters.
|
9
|
+
Metrics/LineLength:
|
10
|
+
Max: 140
|
11
|
+
|
12
|
+
# Too short methods lead to extraction of single-use methods, which can make
|
13
|
+
# the code easier to read (by naming things), but can also clutter the class
|
14
|
+
Metrics/MethodLength:
|
15
|
+
Max: 20
|
16
|
+
|
17
|
+
# The guiding principle of classes is SRP, SRP can't be accurately measured by LoC
|
18
|
+
Metrics/ClassLength:
|
19
|
+
Max: 1500
|
20
|
+
|
21
|
+
# Single quotes being faster is hardly measurable and only affects parse time.
|
22
|
+
# Enforcing double quotes reduces the times where you need to change them
|
23
|
+
# when introducing an interpolation. Use single quotes only if their semantics
|
24
|
+
# are needed.
|
25
|
+
#Style/StringLiterals:
|
26
|
+
# EnforcedStyle: double_quotes
|
27
|
+
|
28
|
+
# Frozen string literals may be default in Ruby 3.0. Default Enabled: true
|
29
|
+
# See more: https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Style/FrozenStringLiteralComment
|
30
|
+
FrozenStringLiteralComment:
|
31
|
+
Enabled: true
|
32
|
+
|
33
|
+
# Style/ClassAndModuleChildren:
|
34
|
+
# EnforcedStyle: compact
|
35
|
+
|
36
|
+
# We do not need to support Ruby 1.9, so this is good to use.
|
37
|
+
Style/SymbolArray:
|
38
|
+
Enabled: true
|
39
|
+
|
40
|
+
# Disabled warning DateTime
|
41
|
+
Style/DateTime:
|
42
|
+
Enabled: false
|
43
|
+
|
44
|
+
# Disabled Style/Documentation
|
45
|
+
Style/Documentation:
|
46
|
+
Enabled: false
|
47
|
+
|
48
|
+
# Disabled เพื่อคอมเม้นภาษาไทยด้ายยยยยยยย
|
49
|
+
Style/AsciiComments:
|
50
|
+
Enabled: false
|
51
|
+
|
52
|
+
Metrics/AbcSize:
|
53
|
+
Max: 20
|
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
0.3.5 / 2019-10-11
|
2
|
+
---
|
3
|
+
- Rework perform method in `StockShaker::Client::LazadaOP`
|
4
|
+
|
5
|
+
0.3.4 / 2019-09-30
|
6
|
+
---
|
7
|
+
- Create new `StockShaker::Concern::Utility`
|
8
|
+
- Rework Utility -> DateUtil
|
9
|
+
- Rework `client/lazada_op`
|
10
|
+
- Remove `active_support` from dependencies
|
11
|
+
|
12
|
+
0.3.3 / 2018-10-8
|
13
|
+
---
|
14
|
+
- assign `business_params`
|
15
|
+
```ruby
|
16
|
+
# lib/stock_shaker/request/jd_central_op.rb
|
17
|
+
# JDCentralOP#add_business_params line 24 - 26
|
18
|
+
|
19
|
+
@business_params = {
|
20
|
+
param_json: hash.to_json
|
21
|
+
}
|
22
|
+
```
|
23
|
+
|
24
|
+
0.3.2 / 2018-10-4
|
25
|
+
---
|
26
|
+
- Added JD Central (TH) Integration
|
27
|
+
|
28
|
+
0.3.1 / 2018-08-14
|
29
|
+
---
|
30
|
+
- Return ::Client::ShopeeOP.perform as Object type not a JSON
|
31
|
+
|
32
|
+
0.3.0 / 2018-08-03
|
33
|
+
---
|
34
|
+
- Merge conflict
|
35
|
+
|
36
|
+
|
37
|
+
0.2.9 / 2018-08-3
|
38
|
+
---
|
39
|
+
- Added `rescue StandardError` for `ShopeeOP::Client.perform`
|
40
|
+
|
41
|
+
0.2.8 / 2018-07-26
|
42
|
+
---
|
43
|
+
- Update gemspec
|
44
|
+
|
45
|
+
0.2.7 / 2018-07-26
|
46
|
+
---
|
47
|
+
- Refactoring and publish beta version.
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2018 Nathakorn Chaninthanadecha
|
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,263 @@
|
|
1
|
+
<p align="center">
|
2
|
+
<a href="https://rubygems.org/gems/stock_shaker"><img src="https://github.com/nijicha/stock_shaker/blob/master/media/icon.png?raw=true" height="240" alt="Stock Shaker Logo" /></a>
|
3
|
+
<h3 align="center">Stock Shaker</h3>
|
4
|
+
<p align="center">Unofficial Rubygems for Thailand eCommerce Marketplace</p>
|
5
|
+
|
6
|
+
<p align="center">
|
7
|
+
<img src="https://img.shields.io/github/stars/nijicha/stock_shaker.svg?style=for-the-badge&label=Stars" alt="Github Stars" >
|
8
|
+
<a href="https://rubygems.org/gems/stock_shaker"><img src="https://img.shields.io/gem/v/stock_shaker.svg?style=for-the-badge" alt="Gem Version"></a>
|
9
|
+
<a href="https://travis-ci.org/nijicha/stock_shaker"><img src="https://img.shields.io/travis/nijicha/stock_shaker/master.svg?style=for-the-badge" alt="Branch master Travis-ci Build Status"></a>
|
10
|
+
<a href="https://github.com/nijicha/stock_shaker/blob/master/LICENSE.txt"><img src="https://img.shields.io/github/license/nijicha/stock_shaker.svg?style=for-the-badge" alt="License" /></a>
|
11
|
+
</p>
|
12
|
+
<p align="center">
|
13
|
+
<a href="https://forthebadge.com"><img src="https://forthebadge.com/images/badges/built-with-love.svg" alt="For The Badge Built with Love" height="28"></a>
|
14
|
+
<a href="https://forthebadge.com"><img src="https://forthebadge.com/images/badges/made-with-ruby.svg" alt="For The Badge Made with Ruby" height="28"></a>
|
15
|
+
<a href="https://shields.io/"><img src="https://github.com/nijicha/stock_shaker/blob/master/media/badge/made_with-shield_io-green.svg" alt="Shield.io Made with shield.io" /></a>
|
16
|
+
</p>
|
17
|
+
<p align="center">
|
18
|
+
<a href="https://www.lazada.co.th/"><img src="https://github.com/nijicha/stock_shaker/blob/master/media/badge/market_place_support/love-lazada-sky-blue.svg" alt="Love Lazada" /></a>
|
19
|
+
<a href="https://www.shopee.co.th/"><img src="https://github.com/nijicha/stock_shaker/blob/master/media/badge/market_place_support/love-shopee-orange.svg" alt="Love Shopee" /></a>
|
20
|
+
</p>
|
21
|
+
</p>
|
22
|
+
|
23
|
+
A gems used to kick off API of eCommerce in Thailand. This gems inspired from [Official Lazada Open Platform Gems](https://rubygems.org/gems/lazop_api_client/versions/1.2.5)
|
24
|
+
|
25
|
+
## Installation
|
26
|
+
|
27
|
+
**StockShaker**'s installation is Easy! Add this line to your application's `Gemfile`
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
gem 'stock_shaker', '~> 0.3.5'
|
31
|
+
```
|
32
|
+
|
33
|
+
If you'd rather install **StockShaker** with ruby-versions below than `2.4`.
|
34
|
+
|
35
|
+
You need to add `openssl` as dependencies in `Gemfile`
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
# Gemfile
|
39
|
+
|
40
|
+
gem 'stock_shaker', '~> 0.3.5'
|
41
|
+
gem 'openssl'
|
42
|
+
```
|
43
|
+
|
44
|
+
And then execute:
|
45
|
+
|
46
|
+
$ bundle install
|
47
|
+
|
48
|
+
Or install it yourself as:
|
49
|
+
|
50
|
+
$ gem install stock_shaker
|
51
|
+
|
52
|
+
## Usage
|
53
|
+
|
54
|
+
### Configurable
|
55
|
+
|
56
|
+
- Create `stock_shaker_config.rb` in `config/initializer`
|
57
|
+
- Please ensure you already configured it.
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
# config/initializer/stock_shaker_config.rb
|
61
|
+
StockShaker.configure do |config|
|
62
|
+
# Lazada Configuration
|
63
|
+
config.lazada_config.app_key = ENV['YOUR_LAZADA_APP_KEY']
|
64
|
+
config.lazada_config.app_secret_key = ENV['YOUR_LAZADA_APP_SECRET_KEY']
|
65
|
+
config.lazada_config.redirect_url = ENV['YOUR_LAZADA_REDIRECT_URL']
|
66
|
+
|
67
|
+
# Shopee Configuration
|
68
|
+
config.shopee_config.partner_id = ENV['YOUR_SHOPEE_PARTNER_ID']
|
69
|
+
config.shopee_config.secret_key = ENV['YOUR_SHOPEE_SECRET_KEY']
|
70
|
+
config.shopee_config.redirect_url = ENV['YOUR_SHOPEE_REDIRECT_URL']
|
71
|
+
end
|
72
|
+
```
|
73
|
+
### Do Authorization Link
|
74
|
+
|
75
|
+
<img src="https://github.com/nijicha/stock_shaker/blob/master/media/badge/stock_shaker-new-orange.svg" alt="NEW API" />
|
76
|
+
|
77
|
+
<b>* You should be define the `StockShaker.configure` before typing this command.</b>
|
78
|
+
|
79
|
+
#### Lazada
|
80
|
+
```ruby
|
81
|
+
StockShaker::Client::LazadaOP.do_authorization_link
|
82
|
+
|
83
|
+
=> "https://auth.lazada.com/oauth/authorize?client_id=YOUR_LAZADA_APP_KEY&force_auth=true&redirect_uri=YOUR_LAZADA_REDIRECT_URL&response_type=code"
|
84
|
+
```
|
85
|
+
|
86
|
+
#### Shopee
|
87
|
+
```ruby
|
88
|
+
StockShaker::Client::ShopeeOP.do_authorization_link
|
89
|
+
|
90
|
+
=> "https://partner.shopeemobile.com/api/v1/shop/auth_partner?id=YOUR_SHOPEE_PARTNER_ID&redirect=YOUR_SHOPEE_REDIRECT_URL&token=AUTHORIZATION_TOKEN"
|
91
|
+
```
|
92
|
+
|
93
|
+
### Lazada Open Platform
|
94
|
+
|
95
|
+
- <img src="https://github.com/nijicha/stock_shaker/blob/master/media/badge/lazada/lazada_api-system--api-yellow.svg" alt="SystemAPI" />
|
96
|
+
|
97
|
+
- <a href="https://open.lazada.com/doc/api.htm?spm=a2o9m.11193487.0.0.3ac413feha8qCs#/api?cid=11&path=/auth/token/create">
|
98
|
+
<img src="https://github.com/nijicha/stock_shaker/blob/master/media/badge/lazada/generate_access_token.svg" alt="Generate Access Token" />
|
99
|
+
</a>
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
server_url = StockShaker::Client::LAZADA_API_GATEWAY_URL_TH
|
103
|
+
lazada_client = StockShaker::Client::LazadaOP.new(server_url)
|
104
|
+
lazada_request = StockShaker::Request::LazadaOP.new('/auth/token/create', :post)
|
105
|
+
lazada_request_params = { code: 'YOUR_AUTHORIZATION_CODE' }
|
106
|
+
lazada_request_params.each { |key, value| request.add_lazada_api_params(key.to_s, value.to_s) }
|
107
|
+
response = lazada_client.execute(lazada_request)
|
108
|
+
response.success?
|
109
|
+
response.body
|
110
|
+
```
|
111
|
+
|
112
|
+
- <a href="https://open.lazada.com/doc/api.htm?spm=a2o9m.11193487.0.0.3ac413feha8qCs#/api?cid=11&path=/auth/token/refresh">
|
113
|
+
<img src="https://github.com/nijicha/stock_shaker/blob/master/media/badge/lazada/refresh_access_token.svg" alt="Refresh Access Token" />
|
114
|
+
</a>
|
115
|
+
|
116
|
+
```ruby
|
117
|
+
server_url = StockShaker::Client::LAZADA_API_GATEWAY_URL_TH
|
118
|
+
lazada_client = StockShaker::Client::LazadaOP.new(server_url)
|
119
|
+
lazada_request = StockShaker::Request::LazadaOP.new('/auth/token/refresh', :post)
|
120
|
+
lazada_request_params = { refresh_token: 'YOUR_REFRESH_TOKEN' }
|
121
|
+
lazada_request_params.each { |key, value| request.add_lazada_api_params(key.to_s, value.to_s) }
|
122
|
+
response = lazada_client.execute(lazada_request)
|
123
|
+
response.success?
|
124
|
+
response.body
|
125
|
+
```
|
126
|
+
|
127
|
+
- <img src="https://github.com/nijicha/stock_shaker/blob/master/media/badge/lazada/lazada_api-order--api-yellow.svg" alt="Lazada OrderAPI" />
|
128
|
+
|
129
|
+
- <a href="https://open.lazada.com/doc/api.htm?spm=a2o9m.11193535.0.0.62a738e4DBO8DQ#/api?cid=8&path=/orders/get">
|
130
|
+
<img src="https://github.com/nijicha/stock_shaker/blob/master/media/badge/lazada/get_orders-get-green.svg" alt="OrderAPI GetOrders" />
|
131
|
+
</a>
|
132
|
+
|
133
|
+
```ruby
|
134
|
+
server_url = StockShaker::Client::LAZADA_API_GATEWAY_URL_TH
|
135
|
+
access_token = ENV['YOUR_ACCESS_TOKEN']
|
136
|
+
lazada_client = StockShaker::Client::LazadaOP.new(server_url)
|
137
|
+
lazada_request = StockShaker::Request::LazadaOP.new('/orders/get', :get)
|
138
|
+
|
139
|
+
# Get orders since last two days by update_after
|
140
|
+
days_backwards = 2 # Get backwards 2 days
|
141
|
+
update_after = StockShaker::DateUtil.datetime_to_iso8601(DateTime.now.beginning_of_day - days_backwards.days)
|
142
|
+
|
143
|
+
lazada_request_params = {
|
144
|
+
created_before: '2018-02-10T16:00:00+07:00',
|
145
|
+
created_after: '2017-02-10T09:00:00+07:00',
|
146
|
+
status: 'shipped',
|
147
|
+
update_before: '2018-02-10T16:00:00+07:00',
|
148
|
+
sort_direction: 'DESC',
|
149
|
+
offset: 0,
|
150
|
+
limit: 100,
|
151
|
+
update_after: update_after,
|
152
|
+
sort_by: 'updated_at'
|
153
|
+
}
|
154
|
+
|
155
|
+
lazada_request_params.each { |key, value| request.add_lazada_api_params(key.to_s, value.to_s) }
|
156
|
+
response = lazada_client.execute(lazada_request, access_token)
|
157
|
+
puts response.success?
|
158
|
+
puts response.body
|
159
|
+
```
|
160
|
+
|
161
|
+
### Shopee Open Platform
|
162
|
+
|
163
|
+
- <img src="https://github.com/nijicha/stock_shaker/blob/master/media/badge/shopee/shopee_api-order--api-yellow.svg" alt="Shopee OrderAPI" />
|
164
|
+
|
165
|
+
- <a href="https://open.shopee.com/documents?module=4&type=1&id=399">
|
166
|
+
<img src="https://github.com/nijicha/stock_shaker/blob/master/media/badge/shopee/get_orders_list-post-green.svg" alt="OrderAPI GetOrdersList" />
|
167
|
+
</a>
|
168
|
+
|
169
|
+
```ruby
|
170
|
+
server_url = StockShaker::Client::SHOPEE_API_GATEWAY_URL_TH
|
171
|
+
shop_id = ENV['YOUR_SHOP_ID']
|
172
|
+
|
173
|
+
update_time_from = StockShaker::DateUtil.datetime_to_timestamp(DateTime.now.beginning_of_day - 2.days)
|
174
|
+
update_time_to = StockShaker::DateUtil.datetime_to_timestamp(DateTime.now)
|
175
|
+
|
176
|
+
client = StockShaker::Client::ShopeeOP.new(server_url, shop_id)
|
177
|
+
request = StockShaker::Request::ShopeeOP.new('/orders/basics', :post)
|
178
|
+
|
179
|
+
request.add_shopee_api_params({
|
180
|
+
update_time_from: update_time_from,
|
181
|
+
update_time_to: update_time_to,
|
182
|
+
pagination_entries_per_page: 100,
|
183
|
+
pagination_offset: 0
|
184
|
+
})
|
185
|
+
|
186
|
+
response = client.execute(request)
|
187
|
+
puts response.body
|
188
|
+
```
|
189
|
+
|
190
|
+
## Compatibility
|
191
|
+
We supported
|
192
|
+
- Ruby MRI 2.2+
|
193
|
+
- Rails 5.0+
|
194
|
+
|
195
|
+
## Need helps!
|
196
|
+
- Contributed this gems!
|
197
|
+
- Write Test!
|
198
|
+
|
199
|
+
## TODO
|
200
|
+
|
201
|
+
### Core
|
202
|
+
|
203
|
+
- [x] Configurable
|
204
|
+
- [ ] Validation
|
205
|
+
- [ ] Generator
|
206
|
+
- [ ] Write Rspec
|
207
|
+
- [ ] Logger
|
208
|
+
- [ ] Sentry.io Integration
|
209
|
+
|
210
|
+
### Lazada
|
211
|
+
See more: [Lazada Open Platform Documentation](https://open.lazada.com/doc/api.htm?spm=a2o9m.11193535.0.0.62a738e4DBO8DQ#/api?cid=8&path=/order/document/get)
|
212
|
+
|
213
|
+
- [ ] Integrate with API reference
|
214
|
+
- [ ] Order API
|
215
|
+
- [x] GetOrders
|
216
|
+
- [x] GetMultipleOrderItems
|
217
|
+
- [ ] Product API
|
218
|
+
- [x] GetProducts
|
219
|
+
- [x] UpdatePriceQuantity
|
220
|
+
- [ ] Finance API
|
221
|
+
- [ ] Logistics API
|
222
|
+
- [ ] Seller API
|
223
|
+
- [x] System API
|
224
|
+
- [x] Generate Access Token
|
225
|
+
- [x] Refresh Access Token
|
226
|
+
- [ ] DataMoat API
|
227
|
+
|
228
|
+
### Shopee
|
229
|
+
See more: [Shopee Open Platform Documentation](https://open.shopee.com/documents)
|
230
|
+
- [ ] Integrate with API reference
|
231
|
+
- ItemAPI
|
232
|
+
- [x] GetItemsList (/items/get)
|
233
|
+
- [x] GetItemDetails (/item/get)
|
234
|
+
- [x] UpdateStock (/items/update_stock)
|
235
|
+
- [x] UpdateStockBatch (/items/update/items_stock)
|
236
|
+
- [x] UpdateVariationStock (/items/update_variation_stock)
|
237
|
+
- [x] UpdateVariationStockBatch (/items/update/vars_stock)
|
238
|
+
- [x] InsertItemImg (/item/img/insert)
|
239
|
+
- [x] DeleteItemImg (/item/img/delete)
|
240
|
+
- OrderAPI
|
241
|
+
- [x] GetOrdersList (/orders/basics)
|
242
|
+
- [x] GetOrdersDetail (/orders/detail)
|
243
|
+
- [x] GetEscrowDetails (/orders/my_income)
|
244
|
+
- ShopAPI
|
245
|
+
- [x] GetPerformance (/shop/performance)
|
246
|
+
|
247
|
+
### JD Central
|
248
|
+
|
249
|
+
- [ ] Integrate with API reference
|
250
|
+
|
251
|
+
## Development
|
252
|
+
1. `git clone https://github.com/nijicha/stock_shaker.git`
|
253
|
+
2. `bundle install`
|
254
|
+
|
255
|
+
## Contributing
|
256
|
+
|
257
|
+
Bug reports and pull requests are welcome on GitHub at [https://github.com/nijicha/stock_shaker](https://github.com/nijicha/stock_shaker).
|
258
|
+
|
259
|
+
This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
260
|
+
|
261
|
+
## License
|
262
|
+
|
263
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'stock_shaker'
|
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(__FILE__)
|
data/bin/setup
ADDED
data/lib/stock_shaker.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'stock_shaker/client/constants'
|
4
|
+
require 'stock_shaker/client/lazada_op'
|
5
|
+
require 'stock_shaker/client/shopee_op'
|
6
|
+
require 'stock_shaker/client/jd_central_op'
|
7
|
+
|
8
|
+
require 'stock_shaker/concern/utility'
|
9
|
+
|
10
|
+
require 'stock_shaker/config'
|
11
|
+
|
12
|
+
require 'stock_shaker/request/lazada_op'
|
13
|
+
require 'stock_shaker/request/shopee_op'
|
14
|
+
require 'stock_shaker/request/jd_central_op'
|
15
|
+
|
16
|
+
require 'stock_shaker/date_util'
|
17
|
+
|
18
|
+
require 'stock_shaker/version'
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module StockShaker
|
4
|
+
module Client
|
5
|
+
# LAZADA
|
6
|
+
LAZADA_API_AUTH_URL = 'https://auth.lazada.com/oauth/authorize'.freeze
|
7
|
+
LAZADA_API_AUTHENTICATION_URL = 'https://auth.lazada.com/rest'.freeze
|
8
|
+
LAZADA_API_GATEWAY_URL_SG = 'https://api.lazada.sg/rest'.freeze
|
9
|
+
LAZADA_API_GATEWAY_URL_MY = 'https://api.lazada.com.my/rest'.freeze
|
10
|
+
LAZADA_API_GATEWAY_URL_VN = 'https://api.lazada.vn/rest'.freeze
|
11
|
+
LAZADA_API_GATEWAY_URL_TH = 'https://api.lazada.co.th/rest'.freeze
|
12
|
+
LAZADA_API_GATEWAY_URL_PH = 'https://api.lazada.com.ph/rest'.freeze
|
13
|
+
LAZADA_API_GATEWAY_URL_ID = 'https://api.lazada.co.id/rest'.freeze
|
14
|
+
|
15
|
+
# SHOPEE
|
16
|
+
SHOPEE_API_AUTH_URL = 'https://partner.shopeemobile.com/api/v1/shop/auth_partner'.freeze
|
17
|
+
SHOPEE_API_CANCEL_AUTH_URL = 'https://partner.shopeemobile.com/api/v1/shop/cancel_auth_partner'.freeze
|
18
|
+
SHOPEE_API_GATEWAY_URL_TH = 'https://partner.shopeemobile.com/api/v1'.freeze
|
19
|
+
|
20
|
+
# JD_CENTRAL
|
21
|
+
JD_CENTRAL_API_GATEWAY_URL_TH = 'https://open.jd.co.th/api'.freeze
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'digest'
|
4
|
+
require 'openssl'
|
5
|
+
require 'rest-client'
|
6
|
+
|
7
|
+
module StockShaker
|
8
|
+
module Client
|
9
|
+
class JDCentralOP
|
10
|
+
attr_reader :common_params, :server_url, :app_secret
|
11
|
+
|
12
|
+
def initialize(server_url, app_secret)
|
13
|
+
@common_params = {
|
14
|
+
timestamp: DateTime.now.strftime('%F %T.%L%z'),
|
15
|
+
format: 'json',
|
16
|
+
v: '1.0'
|
17
|
+
}
|
18
|
+
|
19
|
+
@server_url = server_url
|
20
|
+
@app_secret = app_secret
|
21
|
+
|
22
|
+
validates!
|
23
|
+
end
|
24
|
+
|
25
|
+
def execute(request)
|
26
|
+
request_params = @common_params.merge(**request.api_params, **request.business_params)
|
27
|
+
request_params[:sign] = do_signature(request_params)
|
28
|
+
|
29
|
+
request.add_header_params('charset', 'utf-8')
|
30
|
+
|
31
|
+
perform(request, request_params.as_json)
|
32
|
+
end
|
33
|
+
|
34
|
+
def do_signature(request_params)
|
35
|
+
# Sort key by ASCII rule
|
36
|
+
sorted_params = request_params.sort_by { |key, _value| key }
|
37
|
+
|
38
|
+
# Create sign_base_string
|
39
|
+
sign_base_string = @app_secret
|
40
|
+
sorted_params.each { |key, value| sign_base_string += "#{key}#{value}" }
|
41
|
+
sign_base_string += @app_secret
|
42
|
+
|
43
|
+
# Conditional sign by sign_method
|
44
|
+
if request_params[:sign_method].include?('hmac')
|
45
|
+
digest = OpenSSL::Digest.new('sha256')
|
46
|
+
OpenSSL::HMAC.hexdigest(digest, @app_secret, sign_base_string).upcase
|
47
|
+
else
|
48
|
+
Digest::MD5.hexdigest(sign_base_string).upcase
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def perform(request, request_params)
|
53
|
+
RestClient::Request.execute(
|
54
|
+
method: request.http_method,
|
55
|
+
payload: request_params,
|
56
|
+
url: @server_url,
|
57
|
+
headers: request.header_params
|
58
|
+
)
|
59
|
+
rescue StandardError => err
|
60
|
+
err
|
61
|
+
end
|
62
|
+
|
63
|
+
def validates!
|
64
|
+
raise 'server_url is required' unless @server_url
|
65
|
+
raise 'app_secret is required' unless @app_secret
|
66
|
+
end
|
67
|
+
|
68
|
+
# TODO: May be JD Central issued this in the future
|
69
|
+
def self.do_authorization_link; end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'openssl'
|
5
|
+
require 'rest-client'
|
6
|
+
|
7
|
+
require_relative '../concern/utility'
|
8
|
+
|
9
|
+
module StockShaker
|
10
|
+
module Client
|
11
|
+
class LazadaOP
|
12
|
+
include Concern::Utility
|
13
|
+
|
14
|
+
attr_reader :common_params, :server_url, :rest_url
|
15
|
+
|
16
|
+
def initialize(server_url)
|
17
|
+
@common_params = {
|
18
|
+
app_key: StockShaker.config.lazada_config.app_key,
|
19
|
+
timestamp: (Time.now.to_f * 1000).to_i,
|
20
|
+
sign_method: 'sha256'
|
21
|
+
}
|
22
|
+
@server_url = server_url
|
23
|
+
@rest_url = nil
|
24
|
+
|
25
|
+
validates!
|
26
|
+
end
|
27
|
+
|
28
|
+
def execute(request, access_token = nil)
|
29
|
+
@common_params[:access_token] = access_token if access_token
|
30
|
+
@common_params[:sign] = do_signature(request.api_params, request.api_name)
|
31
|
+
@rest_url = do_rest_url(request.api_name)
|
32
|
+
if request.http_method == :post
|
33
|
+
perform_post(@rest_url, request)
|
34
|
+
else
|
35
|
+
perform_get(@rest_url, request)
|
36
|
+
end
|
37
|
+
|
38
|
+
rescue StandardError => err
|
39
|
+
raise "#{@rest_url}, HTTP_ERROR, #{err.message}"
|
40
|
+
end
|
41
|
+
|
42
|
+
def do_signature(api_params, api_name)
|
43
|
+
params = api_params.nil? ? @common_params : @common_params.merge(api_params)
|
44
|
+
sort_arrays = params.sort_by { |key, _value| key.to_s }
|
45
|
+
|
46
|
+
# See signature pattern : https://open.lazada.com/doc/doc.htm?spm=a2o9m.11193531.0.0.40ed6bbemuDwkW#?nodeId=10451&docId=108069
|
47
|
+
signature_base_string = api_name.to_s
|
48
|
+
sort_arrays.each { |key, value| signature_base_string += "#{key}#{value}" }
|
49
|
+
|
50
|
+
sign_digest = OpenSSL::Digest.new('sha256')
|
51
|
+
secret_key = StockShaker.config.lazada_config.app_secret_key
|
52
|
+
OpenSSL::HMAC.hexdigest(sign_digest, secret_key, signature_base_string).upcase
|
53
|
+
end
|
54
|
+
|
55
|
+
# REVIEW: Regarding to Lazada Open Platform Official rubygem
|
56
|
+
# @common_params didn't sort!!!!
|
57
|
+
# Can't use to_query method for @common_params
|
58
|
+
# Parse hash to query string by manually
|
59
|
+
def do_rest_url(api_name)
|
60
|
+
raise 'Signature should not be blank. Please generate signature by LazadaOP#do_signature.' if @common_params[:sign].blank?
|
61
|
+
length = @server_url.length
|
62
|
+
rest_url = @server_url[(length - 1)] == '/' ? @server_url.chomp!('/') : @server_url
|
63
|
+
|
64
|
+
common_params_string = ''
|
65
|
+
@common_params.each do |key, value|
|
66
|
+
common_params_string += '&' unless common_params_string.blank?
|
67
|
+
common_params_string += "#{key}=#{value}"
|
68
|
+
end
|
69
|
+
"#{rest_url + api_name}?#{common_params_string}"
|
70
|
+
end
|
71
|
+
|
72
|
+
# REVIEW: Regarding to Regarding to Lazada Open Platform Official rubygem
|
73
|
+
# header_params is unused.
|
74
|
+
def perform_get(rest_url, request)
|
75
|
+
query_params = request.api_params.blank? ? '' : to_query_params(request.api_params)
|
76
|
+
url = "#{rest_url}&#{query_params}"
|
77
|
+
|
78
|
+
response = RestClient::Request.execute(
|
79
|
+
method: request.http_method,
|
80
|
+
url: url,
|
81
|
+
headers: request.header_params,
|
82
|
+
read_timeout: 30,
|
83
|
+
open_timeout: 15
|
84
|
+
)
|
85
|
+
JSON.parse(response)
|
86
|
+
end
|
87
|
+
|
88
|
+
def perform_post(rest_url, request)
|
89
|
+
response = RestClient::Request.execute(
|
90
|
+
method: request.http_method,
|
91
|
+
url: rest_url,
|
92
|
+
payload: request.api_params,
|
93
|
+
headers: request.header_params,
|
94
|
+
read_timeout: 30,
|
95
|
+
open_timeout: 15
|
96
|
+
)
|
97
|
+
JSON.parse(response)
|
98
|
+
end
|
99
|
+
|
100
|
+
def validates!
|
101
|
+
raise 'server_url is required' unless @server_url
|
102
|
+
end
|
103
|
+
|
104
|
+
def self.do_authorization_link
|
105
|
+
params = {
|
106
|
+
response_type: 'code',
|
107
|
+
force_auth: true,
|
108
|
+
client_id: StockShaker.config.lazada_config.app_key,
|
109
|
+
redirect_uri: StockShaker.config.lazada_config.redirect_url
|
110
|
+
}
|
111
|
+
|
112
|
+
"#{StockShaker::Client::LAZADA_API_AUTH_URL}?#{to_query_params(params)}"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'digest'
|
4
|
+
require 'openssl'
|
5
|
+
require 'rest-client'
|
6
|
+
|
7
|
+
require_relative '../concern/utility'
|
8
|
+
|
9
|
+
module StockShaker
|
10
|
+
module Client
|
11
|
+
class ShopeeOP
|
12
|
+
include Concern::Utility
|
13
|
+
|
14
|
+
attr_reader :common_params, :server_url, :rest_url
|
15
|
+
|
16
|
+
def initialize(server_url, shop_id)
|
17
|
+
@common_params = {
|
18
|
+
shopid: shop_id.to_i,
|
19
|
+
partner_id: StockShaker.config.shopee_config.partner_id.to_i,
|
20
|
+
timestamp: DateTime.now.to_time.to_i
|
21
|
+
}
|
22
|
+
@server_url = server_url
|
23
|
+
@rest_url = nil
|
24
|
+
validates!
|
25
|
+
end
|
26
|
+
|
27
|
+
def execute(request)
|
28
|
+
request_params = @common_params.merge(request.api_params).to_json
|
29
|
+
@rest_url = "#{@server_url}#{request.api_name}"
|
30
|
+
|
31
|
+
signature = do_signature(@rest_url, request_params)
|
32
|
+
|
33
|
+
request.add_header_params('content-type', 'json')
|
34
|
+
request.add_header_params('Authorization', signature)
|
35
|
+
|
36
|
+
perform(@rest_url, request, request_params)
|
37
|
+
end
|
38
|
+
|
39
|
+
def do_signature(rest_url, request_params)
|
40
|
+
signature_base_string = "#{rest_url}|#{request_params}"
|
41
|
+
OpenSSL::HMAC.hexdigest('SHA256', StockShaker.config.shopee_config.secret_key, signature_base_string)
|
42
|
+
end
|
43
|
+
|
44
|
+
def perform(url, request, request_params)
|
45
|
+
RestClient::Request.execute(
|
46
|
+
method: request.http_method,
|
47
|
+
payload: request_params,
|
48
|
+
url: url,
|
49
|
+
headers: request.header_params
|
50
|
+
)
|
51
|
+
rescue StandardError => err
|
52
|
+
err
|
53
|
+
end
|
54
|
+
|
55
|
+
def validates!
|
56
|
+
raise 'server_url is required' unless @server_url
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.do_authorization_link
|
60
|
+
token_base_string = "#{StockShaker.config.shopee_config.secret_key}#{StockShaker.config.shopee_config.redirect_url}"
|
61
|
+
token = Digest::SHA256.hexdigest(token_base_string)
|
62
|
+
|
63
|
+
params = {
|
64
|
+
id: StockShaker.config.shopee_config.partner_id,
|
65
|
+
token: token,
|
66
|
+
redirect: StockShaker.config.shopee_config.redirect_url
|
67
|
+
}
|
68
|
+
|
69
|
+
"#{StockShaker::Client::SHOPEE_API_AUTH_URL}?#{to_query_params(params)}"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module StockShaker
|
4
|
+
module Concern
|
5
|
+
module Utility
|
6
|
+
def to_query_params(object)
|
7
|
+
base_string = ''
|
8
|
+
|
9
|
+
object.each do |key, value|
|
10
|
+
base_string += '&' if base_string.present?
|
11
|
+
base_string += "#{key}=#{value}"
|
12
|
+
end
|
13
|
+
|
14
|
+
base_string
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'config/lazada_config'
|
4
|
+
require_relative 'config/shopee_config'
|
5
|
+
|
6
|
+
module StockShaker
|
7
|
+
class << self
|
8
|
+
def configure
|
9
|
+
yield config
|
10
|
+
end
|
11
|
+
|
12
|
+
def config
|
13
|
+
@config ||= Config.new
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# TODO: Add validation
|
18
|
+
class Config
|
19
|
+
attr_accessor :lazada_config, :shopee_config
|
20
|
+
|
21
|
+
def initialize
|
22
|
+
@lazada_config = LazadaConfig.new
|
23
|
+
@shopee_config = ShopeeConfig.new
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module StockShaker
|
4
|
+
class Config
|
5
|
+
class LazadaConfig
|
6
|
+
attr_accessor :app_key, :app_secret_key, :redirect_url
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@app_key = nil
|
10
|
+
@app_secret_key = nil
|
11
|
+
@redirect_url = nil
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module StockShaker
|
4
|
+
class Config
|
5
|
+
class ShopeeConfig
|
6
|
+
attr_accessor :partner_id, :secret_key, :redirect_url
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@partner_id = nil
|
10
|
+
@secret_key = nil
|
11
|
+
@redirect_url = nil
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module StockShaker
|
4
|
+
class DateUtil
|
5
|
+
# Parse format for Lazada Open Platform
|
6
|
+
def self.datetime_to_iso8601(datetime)
|
7
|
+
time_format = '%Y-%m-%dT%H:%M:%S'
|
8
|
+
datetime.strftime(time_format)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.datetime_to_timestamp(datetime)
|
12
|
+
datetime.to_time.to_i
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module StockShaker
|
4
|
+
module Request
|
5
|
+
class JDCentralOP
|
6
|
+
attr_reader :http_method, :api_params, :business_params, :header_params
|
7
|
+
|
8
|
+
def initialize(http_method = :post)
|
9
|
+
@http_method = http_method
|
10
|
+
@api_params = {}
|
11
|
+
@business_params = {}
|
12
|
+
@header_params = {}
|
13
|
+
|
14
|
+
validate!
|
15
|
+
end
|
16
|
+
|
17
|
+
def add_api_params(hash)
|
18
|
+
raise 'api_params is not hash' unless hash.is_a? Hash
|
19
|
+
@api_params = hash
|
20
|
+
end
|
21
|
+
|
22
|
+
def add_business_params(hash)
|
23
|
+
raise 'business_params is not hash' unless hash.is_a? Hash
|
24
|
+
@business_params = {
|
25
|
+
param_json: hash.to_json
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
def add_header_params(key, value)
|
30
|
+
raise 'header param key is not String' unless key.is_a? String
|
31
|
+
raise 'header param value is not String' unless value.is_a? String
|
32
|
+
@header_params[key] = value
|
33
|
+
end
|
34
|
+
|
35
|
+
def validate!
|
36
|
+
raise 'http_method accepted only :post' unless @http_method.eql?(:post)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module StockShaker
|
4
|
+
module Request
|
5
|
+
class LazadaOP
|
6
|
+
attr_reader :api_name, :http_method, :api_params, :header_params
|
7
|
+
|
8
|
+
def initialize(api_name = nil, http_method = :post)
|
9
|
+
@api_name = api_name
|
10
|
+
@http_method = http_method
|
11
|
+
@api_params = {}
|
12
|
+
@header_params = {}
|
13
|
+
|
14
|
+
validate!
|
15
|
+
end
|
16
|
+
|
17
|
+
def add_api_params(key, value)
|
18
|
+
raise 'api_params key is not String' unless key.is_a? String
|
19
|
+
raise 'api_params value is not String' unless value.is_a? String
|
20
|
+
@api_params[key] = value
|
21
|
+
end
|
22
|
+
|
23
|
+
def add_header_params(key, value)
|
24
|
+
raise 'header param key is not String' unless key.is_a? String
|
25
|
+
raise 'header param value is not String' unless value.is_a? String
|
26
|
+
@header_params[key] = value
|
27
|
+
end
|
28
|
+
|
29
|
+
def validate!
|
30
|
+
raise 'api_name is required' if @api_name.blank?
|
31
|
+
raise 'http_method accepted only :get or :post' unless %i[get post].include?(@http_method)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module StockShaker
|
4
|
+
module Request
|
5
|
+
class ShopeeOP
|
6
|
+
attr_reader :api_name, :http_method, :api_params, :header_params
|
7
|
+
|
8
|
+
def initialize(api_name = nil, http_method = :post)
|
9
|
+
@api_name = api_name
|
10
|
+
@http_method = http_method
|
11
|
+
@api_params = {}
|
12
|
+
@header_params = {}
|
13
|
+
|
14
|
+
validate!
|
15
|
+
end
|
16
|
+
|
17
|
+
def add_api_params(hash)
|
18
|
+
raise 'api_params is not hash' unless hash.is_a? Hash
|
19
|
+
@api_params = hash
|
20
|
+
end
|
21
|
+
|
22
|
+
def add_header_params(key, value)
|
23
|
+
raise 'header param key is not String' unless key.is_a? String
|
24
|
+
raise 'header param value is not String' unless value.is_a? String
|
25
|
+
@header_params[key] = value
|
26
|
+
end
|
27
|
+
|
28
|
+
def validate!
|
29
|
+
raise 'api_name is required' if @api_name.blank?
|
30
|
+
raise 'http_method accepted only :get or :post' unless %i[get post].include?(@http_method)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="293.5" height="28"><g shape-rendering="crispEdges"><path fill="#555" d="M0 0h200.5v28H0z"/><path fill="#97CA00" d="M200.5 0h93v28H200.5z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="100"><text x="1002.5" y="175" transform="scale(.1)" textLength="1765">GENERATE ACCESS TOKEN</text><text x="2470" y="175" font-weight="bold" transform="scale(.1)" textLength="690">GET/POST</text></g> </svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="157" height="28"><g shape-rendering="crispEdges"><path fill="#555" d="M0 0h108v28H0z"/><path fill="#97CA00" d="M108 0h49v28H108z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="100"><text x="540" y="175" transform="scale(.1)" textLength="840">GET ORDERS</text><text x="1325" y="175" font-weight="bold" transform="scale(.1)" textLength="250">GET</text></g> </svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="203" height="28"><g shape-rendering="crispEdges"><path fill="#555" d="M0 0h102v28H0z"/><path fill="#dfb317" d="M102 0h101v28H102z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="100"><text x="510" y="175" transform="scale(.1)" textLength="780">LAZADA API</text><text x="1525" y="175" font-weight="bold" transform="scale(.1)" textLength="770">ORDER-API</text></g> </svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="211" height="28"><g shape-rendering="crispEdges"><path fill="#555" d="M0 0h102v28H0z"/><path fill="#dfb317" d="M102 0h109v28H102z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="100"><text x="510" y="175" transform="scale(.1)" textLength="780">LAZADA API</text><text x="1565" y="175" font-weight="bold" transform="scale(.1)" textLength="850">SYSTEM-API</text></g> </svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="284" height="28"><g shape-rendering="crispEdges"><path fill="#555" d="M0 0h191v28H0z"/><path fill="#97CA00" d="M191 0h93v28H191z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="100"><text x="955" y="175" transform="scale(.1)" textLength="1670">REFRESH ACCESS TOKEN</text><text x="2375" y="175" font-weight="bold" transform="scale(.1)" textLength="690">GET/POST</text></g> </svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="197.5" height="28"><g shape-rendering="crispEdges"><path fill="#555" d="M0 0h100.5v28H0z"/><path fill="#97CA00" d="M100.5 0h97v28H100.5z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="100"><text x="502.5" y="175" transform="scale(.1)" textLength="765">MADE WITH</text><text x="1490" y="175" font-weight="bold" transform="scale(.1)" textLength="730">SHIELD.IO</text></g> </svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="112" height="28"><g shape-rendering="crispEdges"><path fill="#DD4F49" d="M0 0h35v28H0z"/><path fill="#163D50" d="M35 0h77v28H35z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="100"><image x="9" y="7" width="14" height="14" xlink:href="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNTEzcHgiIGhlaWdodD0iNDQ5cHgiIHZpZXdCb3g9IjAgMCA1MTMgNDQ5IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgogICAgPCEtLSBHZW5lcmF0b3I6IFNrZXRjaCA1MS4xICg1NzUwMSkgLSBodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2ggLS0+CiAgICA8dGl0bGU+VW50aXRsZWQ8L3RpdGxlPgogICAgPGRlc2M+Q3JlYXRlZCB3aXRoIFNrZXRjaC48L2Rlc2M+CiAgICA8ZGVmcz48L2RlZnM+CiAgICA8ZyBpZD0iUGFnZS0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgICAgICA8ZyBpZD0iaGVhcnQiIGZpbGw9IiNGRkZGRkYiIGZpbGwtcnVsZT0ibm9uemVybyI+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik00NjMuMywzMS42IEM0MDguNSwtMTUuMSAzMjcsLTYuNyAyNzYuNyw0NS4yIEwyNTcsNjUuNSBMMjM3LjMsNDUuMiBDMTg3LjEsLTYuNyAxMDUuNSwtMTUuMSA1MC43LDMxLjYgQy0xMi4xLDg1LjIgLTE1LjQsMTgxLjQgNDAuOCwyMzkuNSBMMjM0LjMsNDM5LjMgQzI0Ni44LDQ1Mi4yIDI2Ny4xLDQ1Mi4yIDI3OS42LDQzOS4zIEw0NzMuMSwyMzkuNSBDNTI5LjQsMTgxLjQgNTI2LjEsODUuMiA0NjMuMywzMS42IFoiIGlkPSJTaGFwZSI+PC9wYXRoPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+"/><text x="245" y="175" transform="scale(.1)" textLength="-30"></text><text x="735" y="175" font-weight="bold" transform="scale(.1)" textLength="530">LAZADA</text></g> </svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="112" height="28"><g shape-rendering="crispEdges"><path fill="#DD4F49" d="M0 0h35v28H0z"/><path fill="#ED6035" d="M35 0h77v28H35z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="100"><image x="9" y="7" width="14" height="14" xlink:href="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNTEzcHgiIGhlaWdodD0iNDQ5cHgiIHZpZXdCb3g9IjAgMCA1MTMgNDQ5IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgogICAgPCEtLSBHZW5lcmF0b3I6IFNrZXRjaCA1MS4xICg1NzUwMSkgLSBodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2ggLS0+CiAgICA8dGl0bGU+VW50aXRsZWQ8L3RpdGxlPgogICAgPGRlc2M+Q3JlYXRlZCB3aXRoIFNrZXRjaC48L2Rlc2M+CiAgICA8ZGVmcz48L2RlZnM+CiAgICA8ZyBpZD0iUGFnZS0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgICAgICA8ZyBpZD0iaGVhcnQiIGZpbGw9IiNGRkZGRkYiIGZpbGwtcnVsZT0ibm9uemVybyI+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik00NjMuMywzMS42IEM0MDguNSwtMTUuMSAzMjcsLTYuNyAyNzYuNyw0NS4yIEwyNTcsNjUuNSBMMjM3LjMsNDUuMiBDMTg3LjEsLTYuNyAxMDUuNSwtMTUuMSA1MC43LDMxLjYgQy0xMi4xLDg1LjIgLTE1LjQsMTgxLjQgNDAuOCwyMzkuNSBMMjM0LjMsNDM5LjMgQzI0Ni44LDQ1Mi4yIDI2Ny4xLDQ1Mi4yIDI3OS42LDQzOS4zIEw0NzMuMSwyMzkuNSBDNTI5LjQsMTgxLjQgNTI2LjEsODUuMiA0NjMuMywzMS42IFoiIGlkPSJTaGFwZSI+PC9wYXRoPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+"/><text x="245" y="175" transform="scale(.1)" textLength="-30"></text><text x="735" y="175" font-weight="bold" transform="scale(.1)" textLength="530">SHOPEE</text></g> </svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200.5" height="28"><g shape-rendering="crispEdges"><path fill="#555" d="M0 0h143.5v28H0z"/><path fill="#97CA00" d="M143.5 0h57v28H143.5z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="100"><text x="717.5" y="175" transform="scale(.1)" textLength="1195">GET ORDERS LIST</text><text x="1720" y="175" font-weight="bold" transform="scale(.1)" textLength="330">POST</text></g> </svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="203" height="28"><g shape-rendering="crispEdges"><path fill="#555" d="M0 0h102v28H0z"/><path fill="#dfb317" d="M102 0h101v28H102z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="100"><text x="510" y="175" transform="scale(.1)" textLength="780">SHOPEE API</text><text x="1525" y="175" font-weight="bold" transform="scale(.1)" textLength="770">ORDER-API</text></g> </svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="178" height="28"><g shape-rendering="crispEdges"><path fill="#555" d="M0 0h125v28H0z"/><path fill="#fe7d37" d="M125 0h53v28H125z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="100"><text x="625" y="175" transform="scale(.1)" textLength="1010">STOCK SHAKER</text><text x="1515" y="175" font-weight="bold" transform="scale(.1)" textLength="290">NEW</text></g> </svg>
|
data/media/icon.png
ADDED
Binary file
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'stock_shaker/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = 'stock_shaker'
|
9
|
+
spec.version = StockShaker::VERSION
|
10
|
+
spec.platform = Gem::Platform::RUBY
|
11
|
+
spec.required_ruby_version = '>= 2.3.0'
|
12
|
+
spec.authors = ['Nathakorn Chaninthanadecha']
|
13
|
+
spec.email = ['nathakorn.tonch@gmail.com']
|
14
|
+
|
15
|
+
spec.homepage = 'https://github.com/nijicha/stock_shaker'
|
16
|
+
spec.license = 'MIT'
|
17
|
+
spec.summary = <<-SUMMARY
|
18
|
+
Kick off API for eCommerce in Thailand.
|
19
|
+
SUMMARY
|
20
|
+
spec.description = <<-DESCRIPTION
|
21
|
+
Unofficial Rubygems for Thailand eCommerce Marketplace.
|
22
|
+
DESCRIPTION
|
23
|
+
|
24
|
+
spec.metadata = {
|
25
|
+
'homepage_uri' => 'https://rubygems.org/gems/stock_shaker',
|
26
|
+
'changelog_uri' => 'https://github.com/nijicha/stock_shaker/blob/master/CHANGELOG.md',
|
27
|
+
'source_code_uri' => 'https://github.com/nijicha/stock_shaker',
|
28
|
+
'bug_tracker_uri' => 'https://github.com/nijicha/stock_shaker/issues'
|
29
|
+
}
|
30
|
+
|
31
|
+
# Specify which files should be added to the gem when it is released.
|
32
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
33
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
34
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
35
|
+
end
|
36
|
+
spec.bindir = 'exe'
|
37
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
38
|
+
spec.require_paths = ['lib']
|
39
|
+
|
40
|
+
spec.add_runtime_dependency 'rest-client', '~> 2.0', '>= 2.0.2'
|
41
|
+
|
42
|
+
spec.add_development_dependency 'bundler', '~> 1.16'
|
43
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
44
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
45
|
+
spec.add_development_dependency 'rubocop', '~> 0.57.2'
|
46
|
+
end
|
metadata
ADDED
@@ -0,0 +1,161 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: stock_shaker
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.5
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nathakorn Chaninthanadecha
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-10-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rest-client
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 2.0.2
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '2.0'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 2.0.2
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: bundler
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '1.16'
|
40
|
+
type: :development
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '1.16'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rake
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '10.0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '10.0'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: rspec
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '3.0'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '3.0'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: rubocop
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: 0.57.2
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - "~>"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: 0.57.2
|
89
|
+
description: " Unofficial Rubygems for Thailand eCommerce Marketplace.\n"
|
90
|
+
email:
|
91
|
+
- nathakorn.tonch@gmail.com
|
92
|
+
executables: []
|
93
|
+
extensions: []
|
94
|
+
extra_rdoc_files: []
|
95
|
+
files:
|
96
|
+
- ".gitignore"
|
97
|
+
- ".rspec"
|
98
|
+
- ".rubocop.yml"
|
99
|
+
- ".travis.yml"
|
100
|
+
- CHANGELOG.md
|
101
|
+
- Gemfile
|
102
|
+
- LICENSE.txt
|
103
|
+
- README.md
|
104
|
+
- Rakefile
|
105
|
+
- bin/console
|
106
|
+
- bin/setup
|
107
|
+
- lib/stock_shaker.rb
|
108
|
+
- lib/stock_shaker/client/constants.rb
|
109
|
+
- lib/stock_shaker/client/jd_central_op.rb
|
110
|
+
- lib/stock_shaker/client/lazada_op.rb
|
111
|
+
- lib/stock_shaker/client/shopee_op.rb
|
112
|
+
- lib/stock_shaker/concern/utility.rb
|
113
|
+
- lib/stock_shaker/config.rb
|
114
|
+
- lib/stock_shaker/config/lazada_config.rb
|
115
|
+
- lib/stock_shaker/config/shopee_config.rb
|
116
|
+
- lib/stock_shaker/date_util.rb
|
117
|
+
- lib/stock_shaker/request/jd_central_op.rb
|
118
|
+
- lib/stock_shaker/request/lazada_op.rb
|
119
|
+
- lib/stock_shaker/request/shopee_op.rb
|
120
|
+
- lib/stock_shaker/version.rb
|
121
|
+
- media/badge/lazada/generate_access_token.svg
|
122
|
+
- media/badge/lazada/get_orders-get-green.svg
|
123
|
+
- media/badge/lazada/lazada_api-order--api-yellow.svg
|
124
|
+
- media/badge/lazada/lazada_api-system--api-yellow.svg
|
125
|
+
- media/badge/lazada/refresh_access_token.svg
|
126
|
+
- media/badge/made_with-shield_io-green.svg
|
127
|
+
- media/badge/market_place_support/love-lazada-sky-blue.svg
|
128
|
+
- media/badge/market_place_support/love-shopee-orange.svg
|
129
|
+
- media/badge/shopee/get_orders_list-post-green.svg
|
130
|
+
- media/badge/shopee/shopee_api-order--api-yellow.svg
|
131
|
+
- media/badge/stock_shaker-new-orange.svg
|
132
|
+
- media/icon.png
|
133
|
+
- stock_shaker.gemspec
|
134
|
+
homepage: https://github.com/nijicha/stock_shaker
|
135
|
+
licenses:
|
136
|
+
- MIT
|
137
|
+
metadata:
|
138
|
+
homepage_uri: https://rubygems.org/gems/stock_shaker
|
139
|
+
changelog_uri: https://github.com/nijicha/stock_shaker/blob/master/CHANGELOG.md
|
140
|
+
source_code_uri: https://github.com/nijicha/stock_shaker
|
141
|
+
bug_tracker_uri: https://github.com/nijicha/stock_shaker/issues
|
142
|
+
post_install_message:
|
143
|
+
rdoc_options: []
|
144
|
+
require_paths:
|
145
|
+
- lib
|
146
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
147
|
+
requirements:
|
148
|
+
- - ">="
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: 2.3.0
|
151
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
152
|
+
requirements:
|
153
|
+
- - ">="
|
154
|
+
- !ruby/object:Gem::Version
|
155
|
+
version: '0'
|
156
|
+
requirements: []
|
157
|
+
rubygems_version: 3.0.3
|
158
|
+
signing_key:
|
159
|
+
specification_version: 4
|
160
|
+
summary: Kick off API for eCommerce in Thailand.
|
161
|
+
test_files: []
|