shopify_sales_channel 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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: aff59b88a0c7a1afae30e54f3d9a5740bc108ba0
4
+ data.tar.gz: aed9f66dcedf08d944a5a36e1c8540510f849946
5
+ SHA512:
6
+ metadata.gz: 80119f7ebb15019006500806453dc44b43b538f2f47a5226f4a4cbfc444d15077dfaf18b6ac672b939251affb065fc981b2c2b7f94f193a112418c970fcef1e6
7
+ data.tar.gz: cedfd44920296e148761f2065fbdfc9973f5fb5e73f9258152fd8b28f0f18e5ffed59efaa1e7f34406df06bc1bd7fa5977704e75fa20062fc31174097b77c68f
@@ -0,0 +1,20 @@
1
+ Copyright 2017
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,28 @@
1
+ # ShopifySalesChannel
2
+ Short description and motivation.
3
+
4
+ ## Usage
5
+ How to use my plugin.
6
+
7
+ ## Installation
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'shopify_sales_channel'
12
+ ```
13
+
14
+ And then execute:
15
+ ```bash
16
+ $ bundle
17
+ ```
18
+
19
+ Or install it yourself as:
20
+ ```bash
21
+ $ gem install shopify_sales_channel
22
+ ```
23
+
24
+ ## Contributing
25
+ Contribution directions go here.
26
+
27
+ ## License
28
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -0,0 +1,33 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'ShopifySalesChannel'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+
18
+
19
+
20
+
21
+
22
+ require 'bundler/gem_tasks'
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'test'
28
+ t.pattern = 'test/**/*_test.rb'
29
+ t.verbose = false
30
+ end
31
+
32
+
33
+ task default: :test
@@ -0,0 +1,36 @@
1
+ module ShopifySalesChannel
2
+ # Your code goes here...
3
+ require "shopify_sales_channel/integrations"
4
+ require "shopify_sales_channel/integrations/shopify"
5
+ require "json"
6
+
7
+ def initialize_sales_channel
8
+ attr_accessor :url, :access_token, :code
9
+ self.class_eval do
10
+ def initialize_store(&param)
11
+ ShopifySalesChannel::Store.new.tap(&param)
12
+ end
13
+ end
14
+ end
15
+
16
+ class Store
17
+ attr_accessor :url, :access_token, :code, :webhook_address, :client_id, :client_secret
18
+
19
+ include ShopifySalesChannel::Integrations
20
+
21
+ def initialize(options={})
22
+ self.url = options[:url]
23
+ self.access_token = options[:access_token]
24
+ self.code = options[:code]
25
+ end
26
+ # def init_store
27
+ # ShopifySalesChannel::Store.new.tap do |store|
28
+ # self.access_token = store.access_token
29
+ # end
30
+ # end
31
+ end
32
+
33
+ def self.configure(&param)
34
+ ShopifySalesChannel::Store.new.tap(&param)
35
+ end
36
+ end
@@ -0,0 +1,38 @@
1
+ module ShopifySalesChannel::Integrations
2
+ def self.included(sub_klass)
3
+ sub_klass.extend ShopifySalesChannel::Integrations::Shopify
4
+ end
5
+
6
+ def get_access_token
7
+ return self.class.get_access_token(code, url)
8
+ end
9
+
10
+ def get_store_details
11
+ return self.class.get_store_details(access_token, url)
12
+ end
13
+
14
+ def set_webhooks
15
+ return self.class.get_store_details(self)
16
+ end
17
+
18
+ def sync_orders
19
+ return self.class.sync_orders(self, self.data["orders"], self.data["country"])
20
+ end
21
+
22
+ def count_products
23
+ return self.class.count_products(self)
24
+ end
25
+
26
+
27
+ def check_products
28
+ return self.class.check_products(self, self.data["orders"])
29
+ end
30
+
31
+ def get_order
32
+ return self.class.get_order(self, self.order_no)
33
+ end
34
+
35
+ def add_tag_to_order
36
+ return self.class.add_tag_to_order(self, self.order_no, self.data["tag"])
37
+ end
38
+ end
@@ -0,0 +1,171 @@
1
+ module ShopifySalesChannel::Integrations::Shopify
2
+ def get_access_token(code, shop_url)
3
+ token_params = {'code' => code, 'client_id' => SHOPIFY_CLIENT_ID, 'client_secret' => SHOPIFY_CLIENT_SECRET}
4
+ response = Net::HTTP.post_form(URI.parse("https://#{shop_url}/admin/oauth/access_token"), token_params)
5
+ response = JSON.parse(response.body)
6
+ store_details = get_store_details(response["access_token"], shop_url)
7
+ response = response.merge!(store_details["shop"])
8
+ end
9
+
10
+ def get_store_details(access_token, shop_name)
11
+ url = URI("https://#{shop_name}/admin/shop.json")
12
+ http = Net::HTTP.new(url.host, url.port)
13
+ http.use_ssl = true
14
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
15
+ request = Net::HTTP::Get.new(url)
16
+ request["x-shopify-access-token"] = access_token
17
+ response = http.request(request)
18
+ response = JSON.parse(response.body)
19
+ return response
20
+ end
21
+
22
+ def set_webhooks(store)
23
+ url = URI("https://#{store.url}/admin/webhooks.json")
24
+
25
+ http = Net::HTTP.new(url.host, url.port)
26
+ http.use_ssl = true
27
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
28
+
29
+ request = Net::HTTP::Post.new(url)
30
+ request["x-shopify-access-token"] = store.access_token
31
+ request["content-type"] = 'application/json'
32
+ SHOPIFY_WEBHOOKS.each do |webhook|
33
+ request.body = {"webhook" => {"topic" => webhook, "address" => "#{HOST}/#{webhook}", "format" => "json"}}.to_json
34
+ response = http.request(request)
35
+ response = JSON.parse(response.body)
36
+ unless response["errors"]
37
+ #do something
38
+ end
39
+ end
40
+ end
41
+
42
+ # def get_customers(store)
43
+ # customers = []
44
+ # store.marketplaces.each do |marketplace|
45
+ # url = URI("https://#{store.domain}/admin/customers.json")
46
+ # http = Net::HTTP.new(url.host, url.port)
47
+ # http.use_ssl = true
48
+ # http.verify_mode = OpenSSL::SSL::VERIFY_NONE
49
+ #
50
+ # request = Net::HTTP::Get.new(url)
51
+ # request["x-shopify-access-token"] = store.access_token
52
+ # response = http.request(request)
53
+ # response = JSON.parse(response.body)
54
+ # response["customers"].each do |customer|
55
+ # name = {"name"=> "#{customer["first_name"]} #{customer["last_name"]}"}
56
+ # customers << (customer.merge!(name))
57
+ # end
58
+ # return customers
59
+ # end
60
+ # end
61
+
62
+ def sync_orders(store, orders, marketplace)
63
+ order = orders.first
64
+ if check_products(store, orders)
65
+ url = URI("https://#{store.url}/admin/orders.json")
66
+
67
+ http = Net::HTTP.new(url.host, url.port)
68
+ http.use_ssl = true
69
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
70
+ request = Net::HTTP::Post.new(url)
71
+ request["x-shopify-access-token"] = store.access_token
72
+ request["content-type"] = 'application/json'
73
+ cust_name = separate_name(order["ordNm"])
74
+ rec_name = separate_name(order["rcvrNm"])
75
+ line_items = []
76
+ store.variants.map{|v| line_items << {"variant_id" => v["id"], "quantity" => v["order_quantity"]}}
77
+ base_addr_arr = order["rcvrBaseAddr"].split(",")
78
+ state = base_addr_arr.pop.squish || "."
79
+ city_and_postal_code = base_addr_arr.join(" ").split(" ")
80
+ city = city_and_postal_code[1..-1].try(:first) || "."
81
+ postcode = order["rcvrMailNo"] || city_and_postal_code[0]
82
+ request.body = {"order" => {"line_items": line_items, "customer": {"first_name": cust_name[0], "last_name": cust_name[1], "email": order["ordEmail"]}, "shipping_address": {"first_name": rec_name[0], "last_name": rec_name[1], "address1": order["rcvrDtlsAddr"], "city": city, "province": state, "country": marketplace.country, "phone": order["rcvrTlphn"], "zip": postcode}}}.to_json
83
+ response = http.request(request)
84
+ response = JSON.parse(response.body)
85
+ response
86
+ else
87
+ store.errors.add(:base, "products not present for order #{order['ordNo']}")
88
+ return false
89
+ end
90
+ end
91
+
92
+ def separate_name(name)
93
+ name_array = name.split(" ")
94
+ first_name = name_array[0]
95
+ last_name = name_array[1..-1].join(" ")
96
+ last_name = "." unless last_name.present?
97
+ separate_name = [first_name, last_name]
98
+ end
99
+
100
+ def count_products(store)
101
+ url = URI("https://#{store.url}/admin/products/count.json")
102
+ http = Net::HTTP.new(url.host, url.port)
103
+ http.use_ssl = true
104
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
105
+
106
+ request = Net::HTTP::Get.new(url)
107
+ request["x-shopify-access-token"] = store.access_token
108
+ request["content-type"] = 'application/json'
109
+ response = http.request(request)
110
+ count = JSON.parse(response.read_body)["count"]
111
+ return count
112
+ end
113
+
114
+
115
+ def check_products(store, orders)
116
+ url = URI("https://#{store.url}/admin/products.json?limit=150")
117
+
118
+ http = Net::HTTP.new(url.host, url.port)
119
+ http.use_ssl = true
120
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
121
+
122
+ request = Net::HTTP::Get.new(url)
123
+ request["x-shopify-access-token"] = store.access_token
124
+ request["content-type"] = 'application/json'
125
+ response = http.request(request)
126
+ products = JSON.parse(response.read_body)["products"]
127
+ flag = true
128
+ variants = []
129
+ order_sku_qty = orders.map{|x| [x["partCode"], x["ordQty"]] if x["partCode"].present?} | orders.map{|x| [x["sellerPrdCd"], x["ordQty"]] if x["sellerPrdCd"].present?}
130
+ order_sku_hash = order_sku_qty.compact.to_h
131
+ products.each do |product|
132
+ product["variants"].each do |variant|
133
+ order_skus = order_sku_hash.keys
134
+ if (order_skus.include?(variant["sku"]))
135
+ variant["order_quantity"] = order_sku_hash[variant["sku"]]
136
+ variant["pre_order"] = true if product["tags"].split(", ").include?("pre-order")
137
+ variants << variant
138
+ end
139
+ end
140
+ end
141
+ #variants = variants.select{|variant| (variant["sku"] == orders["partCode"] || variant["sku"] == orders["sellerPrdCd"])}
142
+ store.variants = variants
143
+ flag = false if variants.blank?
144
+ return flag
145
+ end
146
+
147
+ def get_order(store, order_no)
148
+ url = URI("https://#{store.url}/admin/orders/#{order_no}.json")
149
+ http = Net::HTTP.new(url.host, url.port)
150
+ http.use_ssl = true
151
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
152
+ request = Net::HTTP::Get.new(url)
153
+ request["x-shopify-access-token"] = store.access_token
154
+ response = http.request(request)
155
+ JSON.parse(response.read_body)
156
+ end
157
+
158
+ def add_tag_to_order(store, order_no, data)
159
+ url = URI("https://#{store.url}/admin/orders/#{order_no}.json")
160
+ http = Net::HTTP.new(url.host, url.port)
161
+ http.use_ssl = true
162
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
163
+ request = Net::HTTP::Put.new(url)
164
+ request["content-type"] = 'application/json'
165
+ request["x-shopify-access-token"] = store.access_token
166
+ request.body = {"order": { "tags": data.to_s }}.to_json
167
+
168
+ response = http.request(request)
169
+ puts response.read_body
170
+ end
171
+ end
@@ -0,0 +1,3 @@
1
+ module ShopifySalesChannel
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :shopify_sales_channel do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: shopify_sales_channel
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - ''
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-10-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 5.1.4
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 5.1.4
27
+ - !ruby/object:Gem::Dependency
28
+ name: sqlite3
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Description of ShopifySalesChannel.
42
+ email:
43
+ - ''
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - MIT-LICENSE
49
+ - README.md
50
+ - Rakefile
51
+ - lib/shopify_sales_channel.rb
52
+ - lib/shopify_sales_channel/integrations.rb
53
+ - lib/shopify_sales_channel/integrations/shopify.rb
54
+ - lib/shopify_sales_channel/version.rb
55
+ - lib/tasks/shopify_sales_channel_tasks.rake
56
+ homepage: ''
57
+ licenses:
58
+ - MIT
59
+ metadata: {}
60
+ post_install_message:
61
+ rdoc_options: []
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ requirements: []
75
+ rubyforge_project:
76
+ rubygems_version: 2.5.1
77
+ signing_key:
78
+ specification_version: 4
79
+ summary: Summary of ShopifySalesChannel.
80
+ test_files: []