spree_order_groove 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/.gitignore +14 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +7 -0
  4. data/LICENSE +26 -0
  5. data/README.md +60 -0
  6. data/Rakefile +21 -0
  7. data/app/assets/javascripts/spree/backend/spree_order_groove.js +2 -0
  8. data/app/assets/javascripts/spree/frontend/spree_order_groove.js +2 -0
  9. data/app/assets/stylesheets/spree/backend/spree_order_groove.css +4 -0
  10. data/app/assets/stylesheets/spree/frontend/spree_order_groove.css +4 -0
  11. data/app/controllers/spree/api/orders_controller_decorator.rb +293 -0
  12. data/app/controllers/spree/checkout_controller_decorator.rb +102 -0
  13. data/app/controllers/spree/orders_controller_decorator.rb +4 -0
  14. data/app/controllers/spree/store_controller_decorator.rb +24 -0
  15. data/app/models/spree/ordergroove_configuration.rb +12 -0
  16. data/app/models/spree/promotion/rules/autodelivery.rb +23 -0
  17. data/app/overrides/decorate_ordergroove_div_cart.rb +6 -0
  18. data/app/overrides/decorate_ordergroove_div_cart_remove.rb +6 -0
  19. data/app/overrides/decorate_ordergroove_div_product_main.rb +6 -0
  20. data/app/overrides/decorate_ordergroove_tags_cart.rb +6 -0
  21. data/app/overrides/decorate_ordergroove_tags_product.rb +6 -0
  22. data/app/views/spree/admin/promotions/rules/_autodelivery_rule.html.erb +0 -0
  23. data/app/views/spree/api/orders/ogcreateorder.v1.rabl +2 -0
  24. data/app/views/spree/shared/_ordergroove_line_item_div.html.erb +4 -0
  25. data/app/views/spree/shared/_ordergroove_line_item_div_remove.html.erb +3 -0
  26. data/app/views/spree/shared/_ordergroove_tags.html.erb +56 -0
  27. data/bin/rails +7 -0
  28. data/config/locales/en.yml +10 -0
  29. data/config/ordergroove.yml +35 -0
  30. data/config/routes.rb +10 -0
  31. data/db/migrate/20150604115532_add_auto_delivery_to_spree_line_items.spree_order_groove.rb +5 -0
  32. data/lib/generators/spree_order_groove/install/install_generator.rb +31 -0
  33. data/lib/rc4.rb +64 -0
  34. data/lib/spree_order_groove.rb +2 -0
  35. data/lib/spree_order_groove/engine.rb +23 -0
  36. data/lib/spree_order_groove/factories.rb +6 -0
  37. data/spec/spec_helper.rb +87 -0
  38. data/spree_order_groove.gemspec +31 -0
  39. metadata +268 -0
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ \#*
2
+ *~
3
+ .#*
4
+ .DS_Store
5
+ .idea
6
+ .project
7
+ .sass-cache
8
+ coverage
9
+ Gemfile.lock
10
+ tmp
11
+ nbproject
12
+ pkg
13
+ *.swp
14
+ spec/dummy
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'spree', github: 'spree/spree', branch: '3-0-stable'
4
+ # Provides basic authentication functionality for testing parts of your engine
5
+ gem 'spree_auth_devise', github: 'spree/spree_auth_devise', branch: '3-0-stable'
6
+
7
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,26 @@
1
+ Copyright (c) 2015 [name of plugin creator]
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification,
5
+ are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+ * Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+ * Neither the name Spree nor the names of its contributors may be used to
13
+ endorse or promote products derived from this software without specific
14
+ prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,60 @@
1
+ SpreeOrderGroove
2
+ ================
3
+
4
+ Order Groove provide the retain engine for ecommerce web sites, all customer sign up for auto delivery. This spree extension integrate it into spree.
5
+
6
+ Installation
7
+ ------------
8
+
9
+ This extension integrate the classical OrderGroove server. It tags products page, checkout pages, create credit, and provide the drop order API to orderGroove.
10
+
11
+ you need one orderGroove account to test it.
12
+
13
+ This extension assume you are using multi-domain extension or the spree 3.0 which support multi-domain.
14
+ The API call you give to OrderGroove will be:
15
+ yourdomain.com/api/orders/ogcreateorder
16
+
17
+ one example call in linux is:
18
+ curl -X POST -H "Content-Type: text/xml" -d "@the_order_from_ordergroove.xml" --header "X-Spree-Token: the_token_you_authorize_ordergroove" yourdomain.com/api/orders/ogcreateorder
19
+
20
+ Setup in Spree
21
+ ------------
22
+ Create new production, add the rule of Order Groove Auto delivery discount
23
+ you can add other rules to limit it
24
+ Add action for Percent Per Item, and set the percent you want.
25
+
26
+ ```ruby
27
+ gem 'spree_order_groove'
28
+ ```
29
+
30
+ Bundle your dependencies and run the installation generator:
31
+
32
+ ```shell
33
+ bundle
34
+ bundle exec rails g spree_order_groove:install
35
+ ```
36
+
37
+ Testing
38
+ -------
39
+
40
+ First bundle your dependencies, then run `rake`. `rake` will default to building the dummy app if it does not exist, then it will run specs. The dummy app can be regenerated by using `rake test_app`.
41
+
42
+ ```shell
43
+ bundle
44
+ bundle exec rake
45
+ ```
46
+
47
+ When testing your applications integration with this extension you may use it's factories.
48
+ Simply add this require statement to your spec_helper:
49
+
50
+ ```ruby
51
+ require 'spree_order_groove/factories'
52
+ ```
53
+
54
+ register the promotion using this code inside config/initializers/spree.rb:
55
+ Rails.application.config.spree.promotions.rules << Spree::Promotion::Rules::Autodelivery
56
+
57
+ Contact me at albertliu at naturalwellbeing dot com.
58
+
59
+
60
+ Copyright (c) 2015 Naturalwellbeing.com, released under the New BSD License
data/Rakefile ADDED
@@ -0,0 +1,21 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ require 'spree/testing_support/extension_rake'
6
+
7
+ RSpec::Core::RakeTask.new
8
+
9
+ task :default do
10
+ if Dir["spec/dummy"].empty?
11
+ Rake::Task[:test_app].invoke
12
+ Dir.chdir("../../")
13
+ end
14
+ Rake::Task[:spec].invoke
15
+ end
16
+
17
+ desc 'Generates a dummy app for testing'
18
+ task :test_app do
19
+ ENV['LIB_NAME'] = 'spree_order_groove'
20
+ Rake::Task['extension:test_app'].invoke
21
+ end
@@ -0,0 +1,2 @@
1
+ // Placeholder manifest file.
2
+ // the installer will append this file to the app vendored assets here: vendor/assets/javascripts/spree/backend/all.js'
@@ -0,0 +1,2 @@
1
+ // Placeholder manifest file.
2
+ // the installer will append this file to the app vendored assets here: vendor/assets/javascripts/spree/frontend/all.js'
@@ -0,0 +1,4 @@
1
+ /*
2
+ Placeholder manifest file.
3
+ the installer will append this file to the app vendored assets here: 'vendor/assets/stylesheets/spree/backend/all.css'
4
+ */
@@ -0,0 +1,4 @@
1
+ /*
2
+ Placeholder manifest file.
3
+ the installer will append this file to the app vendored assets here: 'vendor/assets/stylesheets/spree/frontend/all.css'
4
+ */
@@ -0,0 +1,293 @@
1
+ Spree::Api::OrdersController.class_eval do
2
+
3
+ skip_before_action :authenticate_user, only: :ogcreateorder
4
+ skip_before_action :find_order, only: :ogcreateorder
5
+
6
+ def ogcreateorder
7
+
8
+ #****************************
9
+ # linux shell call to this api
10
+ # curl -X POST -H "Content-Type: text/xml" -d "@og_test1.xml" --header "X-Spree-Token: your_customers_user_key" local.naturalwellbeing.com:8080/api/orders/ogcreateorder
11
+ # assume og_test1.xml should be in you current folder here. X-Spree-Token is from spree_users
12
+
13
+ #****************************
14
+
15
+ og_logger ||= Logger.new("#{Rails.root}/log/og.log")
16
+ # 0. get the RC4 Hash key
17
+ merchant_id= Spree::OrdergrooveConfiguration.account["#{current_store.code}"]["og_merchant_id"]
18
+ hashkey= Spree::OrdergrooveConfiguration.account["#{current_store.code}"]["og_hashkey"]
19
+ rc4=RC4.new(hashkey)
20
+ #begin
21
+ # 1. parse xml (rails active support)
22
+ #render :text => 'xml for orderOgId is: ' + params['order']['head']['orderOgId']
23
+
24
+ # 2. check all parameters there
25
+ # rails4 seems not recognizing xml as params
26
+ string = request.body.read
27
+ params = Hash.from_xml(string)
28
+
29
+ errstr='parameter in OG xml is not complete'
30
+
31
+ og_logger.info("#{Time.zone.at(Time.new()).strftime("%B %d, %Y at %I:%M PST")} :\n Start processing og dropped order: #{params.to_xml}") # this xml is the re-generated one
32
+ og_logger.info "#params.inspect"
33
+
34
+ # 2.5 validate xml data ingrety
35
+ strxml_error=''
36
+ if params['order']['customer']['customerFirstName'].blank?
37
+ strxml_error += 'customer first name blank,'
38
+ end
39
+ if params['order']['customer']['customerLastName'].blank?
40
+ strxml_error += 'customer last name blank,'
41
+ end
42
+ if params['order']['customer']['customerShippingAddress1'].blank?
43
+ strxml_error += 'customer shipping address blank,'
44
+ end
45
+ if params['order']['customer']['customerShippingCity'].blank?
46
+ strxml_error += 'customer shipping city blank,'
47
+ end
48
+ if params['order']['customer']['customerShippingState'].blank?
49
+ strxml_error += 'customer shipping state blank,'
50
+ end
51
+ if params['order']['customer']['customerShippingCountry'].blank?
52
+ strxml_error += 'customer shipping country blank,'
53
+ end
54
+ if params['order']['customer']['customerShippingZip'].blank?
55
+ strxml_error += 'customer shipping zip code blank,'
56
+ end
57
+ if params['order']['customer']['customerShippingPhone'].blank?
58
+ strxml_error += 'customer shipping phone blank,'
59
+ end
60
+
61
+ if params['order']['customer']['customerBillingAddress1'].blank?
62
+ strxml_error += 'customer Billing address blank,'
63
+ end
64
+ if params['order']['customer']['customerBillingCity'].blank?
65
+ strxml_error += 'customer Billing city blank,'
66
+ end
67
+ if params['order']['customer']['customerBillingState'].blank?
68
+ strxml_error += 'customer Billing state blank,'
69
+ end
70
+ if params['order']['customer']['customerBillingCountry'].blank?
71
+ strxml_error += 'customer Billing country blank,'
72
+ end
73
+ if params['order']['customer']['customerBillingZip'].blank?
74
+ strxml_error += 'customer Billing zip code blank,'
75
+ end
76
+ if params['order']['customer']['customerBillingPhone'].blank?
77
+ strxml_error += 'customer Billing phone blank,'
78
+ end
79
+ if params['order']['customer']['customerPartnerId'].blank? && params['order']['customer']['customerEmail'].blank?
80
+ strxml_error += 'customer customerEmail or customerPartnerId can not be both blank,'
81
+ end
82
+ if strxml_error.length>0
83
+ render :xml =>'<?xml version="1.0" encoding="UTF-8"?><order><code>ERROR</code><errorCode>130</errorCode><errorMsg>' + strxml_error + '</errorMsg></order>'
84
+ else
85
+
86
+
87
+
88
+ # 3. create order
89
+ if params['order']['customer']['customerPartnerId'].blank?
90
+ user=Spree::User.find_by_email(params['order']['customer']['customerEmail'])
91
+ else
92
+ user=Spree::User.find(params['order']['customer']['customerPartnerId'])
93
+ end
94
+ if !user
95
+ render :xml =>'<?xml version="1.0" encoding="UTF-8"?><order><code>ERROR</code><errorCode>130</errorCode><errorMsg>User does not exist</errorMsg></order>'
96
+ else
97
+
98
+ order=user.orders.create(:store_id=>current_store.id, :item_total=>params['order']['head']['orderSubtotalValue'])
99
+
100
+ #order.update_attribute(:user_id, user) unless !user
101
+
102
+ ship_address=Spree::Address.create(:firstname=>params['order']['customer']['customerFirstName'],
103
+ :lastname=>params['order']['customer']['customerLastName'],
104
+ :address1=>params['order']['customer']['customerShippingAddress1'],
105
+ :address2=>params['order']['customer']['customerShippingAddress2'],
106
+ :city=>params['order']['customer']['customerShippingCity'],
107
+ :state_id=>Spree::State.find_by_abbr(params['order']['customer']['customerShippingState']).id.to_s|| '',
108
+ :country_id=>Spree::Country.find_by_iso(params['order']['customer']['customerShippingCountry']).id.to_s||'',
109
+ :zipcode=>params['order']['customer']['customerShippingZip'],
110
+ :phone=>params['order']['customer']['customerShippingPhone']
111
+ )
112
+ ship_address.save!
113
+
114
+ bill_address=Spree::Address.create(:firstname=>params['order']['customer']['customerFirstName'],
115
+ :lastname=>params['order']['customer']['customerLastName'],
116
+ :address1=>params['order']['customer']['customerBillingAddress1'],
117
+ :address2=>params['order']['customer']['customerBillingAddress2'],
118
+ :city=>params['order']['customer']['customerBillingCity'],
119
+ :state_id=>Spree::State.find_by_abbr(params['order']['customer']['customerBillingState']).id.to_s|| '',
120
+ :country_id=>Spree::Country.find_by_iso(params['order']['customer']['customerBillingCountry']).id.to_s||'',
121
+ :zipcode=>params['order']['customer']['customerBillingZip'],
122
+ :phone=>params['order']['customer']['customerBillingPhone']
123
+ )
124
+ bill_address.save!
125
+ if params['order']['customer']['customerShippingCountry']=="CA"
126
+ shipping_method=Spree::ShippingMethod.find_by_code('USP1')
127
+ else
128
+ if ['HI','AK'].include? params['order']['customer']['customerShippingState'] #hi, ak use usps
129
+ shipping_method=Spree::ShippingMethod.find_by_code('M03')||Spree::ShippingMethod.find_by_zone_id_and_code(2,'U11R')
130
+ else
131
+ shipping_method=Spree::ShippingMethod.find_by_code('SUR')||Spree::Zone.find(2).shipping_methods.select{|s|s.code=='FSP'}
132
+ end
133
+ end
134
+ order.update_attributes(:email=>params['order']['customer']['customerEmail'], :ship_address_id=>ship_address.id, :bill_address_id=>bill_address.id, :shipping_method_id => shipping_method.id)
135
+
136
+
137
+
138
+ order.shipments.each do |shipment|
139
+ shipment.update_attributes(:address_id=>ship_address.id,:cost=>params['order']['head']['orderShipping'].to_f)
140
+ end
141
+
142
+
143
+ og_discount=[]
144
+ if params['order']['items']['item'].class == Array
145
+ items=params['order']['items']['item']
146
+ else
147
+ items=[params['order']['items']['item']]
148
+ end
149
+
150
+
151
+
152
+ items.each do |item|
153
+
154
+ #byebug
155
+ variant=Spree::Variant.find(item['product_id'].to_i)
156
+ line_item=order.contents.add(
157
+ variant,
158
+ item['qty'].to_i || 1,
159
+ {auto_delivery: true, price: item['price']}
160
+ )
161
+ Spree::Adjustment.create(:order_id=>order.id, :amount=>item['discount'].to_f*(-1),:label =>'Auto Delivery Discount', :source_type => "Spree::PromotionAction", :adjustable_id => line_item.id, :adjustable_type => "Spree::LineItem") # discount
162
+
163
+
164
+ end
165
+ order.create_proposed_shipments
166
+
167
+ order.line_items.each do |line_item|
168
+ variant=Spree::Variant.find(line_item['variant_id'])
169
+ if (variant.respond_to? :assembly) && variant.assembly?
170
+ variant.parts.each do|v|
171
+ line_item['quantity'].to_i.times {
172
+ v.count.to_i.times {
173
+ order.inventory_units.create(:variant_id=>v.id,:state=>'sold', :shipment_id=>order.shipments.first.id, :line_item_id=>line_item.id)
174
+ }
175
+ }
176
+ end
177
+ else
178
+ line_item['quantity'].to_i.times {
179
+ order.inventory_units.create(:variant_id=>variant.id,:state=>'sold', :shipment_id=>order.shipments.first.id, :line_item_id=>line_item.id)
180
+ }
181
+ end
182
+ end
183
+
184
+
185
+
186
+ order.reload
187
+ #order.update_totals
188
+ order.total = params['order']['head']['orderTotalValue'].to_f
189
+ #order.item_total = params['order']['head']['orderSubtotalValue'].to_f
190
+
191
+ order.line_items.each do |l|
192
+ l.auto_delivery= true
193
+ end
194
+
195
+ #order.save!
196
+ #order.adjustments.first.destroy
197
+
198
+ #order.adjustments.select{|a| a.source_type=="Spree::TaxRate"}.first.amount=params['order']['head']['orderSalesTax'].to_f
199
+ #order.adjustments.select{|a| a.source_type=="Spree::TaxRate"}.first.save!
200
+ Spree::Adjustment.create(:order_id=>order.id, :amount=>params['order']['head']['orderSalesTax'].to_f, :label =>'Tax', :source_type => "Spree::TaxRate", :adjustable_id => order.id, :adjustable_type => "Spree::Order")
201
+
202
+
203
+ #shippings=order.adjustments.select{|a| a.source_type=="Spree::ShippingCharge"}
204
+
205
+ if params['order']['head']['orderShipping'].to_f == 0.00
206
+ # order.adjustments.select{|a| a.type=="ShippingCharge"}.first.destroy
207
+ end
208
+ #order.line_items.each do |line_item|
209
+ #Spree::Adjustment.create(:order_id=>order.id, :amount=>4.5*(-1),:label =>'Auto Delivery Discount', :source_type => "Spree::PromotionAction", :adjustable_id => line_item.id, :adjustable_type => "Spree::LineItem") # discount
210
+ #end
211
+
212
+ order.save!
213
+ # to overwrite the possilbe tax update to 0, reset the total
214
+ order.total = params['order']['head']['orderTotalValue'].to_f
215
+
216
+ # 4. payment
217
+ if params['order']['head']['orderPaymentMethod']== 'CC'
218
+ payment_method=Spree::PaymentMethod.where(:name=>'Credit Card').first
219
+
220
+ payment=Spree::Payment.create(:order_id=>order.id,
221
+ :amount=>order.total,
222
+ :payment_method_id=>payment_method.id
223
+ )
224
+
225
+ expire_date=rc4.decrypt(Base64.decode64(params['order']['head']['orderCcExpire'])).split('/')
226
+ payment.source = payment_method.payment_source_class.new(:number=>rc4.decrypt(Base64.decode64(params['order']['head']['orderCcNumber'])),
227
+ :month=>expire_date[0].to_i.to_s,
228
+ :year=>expire_date[1],
229
+ :verification_value=>213, #params['order']['head']['orderCcNumber'],
230
+ :name=>params['order']['customer']['customerBillingFirstName'] +' '+params['order']['customer']['customerBillingLastName']
231
+ )
232
+
233
+ begin
234
+ payment.source.number=rc4.decrypt(Base64.decode64(params['order']['head']['orderCcNumber']))
235
+ payment_method.create_profile(payment)
236
+ order.total=order.item_total+ order.adjustments.map(&:amount).inject(:+)
237
+
238
+ payment.started_processing!
239
+ payment.pend!
240
+
241
+ order.update_attributes({:state => "complete", :completed_at => Time.now})
242
+ #order.update_attribute(:automated_approved_at, Time.now)
243
+ until order.state == "complete"
244
+ if order.next!
245
+ order.update!
246
+ state_callback(:after)
247
+ end
248
+ end
249
+ order.finalize!
250
+ og_logger.info("og order is successfully created in nwb with number: #{order.number}")
251
+ result_xml='<?xml version="1.0" encoding="UTF-8"?><order><code>SUCCESS</code><orderId>' + order.number + '</orderId><errorMsg /></order>'
252
+ rescue Spree::Core::GatewayError => ge
253
+ # if it fails, destroy the payment and clear the autodelivery discount and flag
254
+ payment.destroy
255
+ order.destroy
256
+ ge=ge.to_s
257
+ error_code='140' #ge.params.messages.message.result_code
258
+ if ge.include? ',,,,,,,,' #this is raw of direct_response
259
+
260
+ response_error_code=ge.split(',')[2]
261
+ if %w(17).include? response_error_code
262
+ error_code='100'
263
+ elsif %w(6,28,37,78).include? response_error_code
264
+ error_code='110'
265
+ elsif %w(7,8).include? response_error_code
266
+ error_code='120'
267
+ elsif %w(27,127).include? response_error_code
268
+ error_code='130'
269
+ end
270
+ error_message = ge.params['message'] || ge.params['response_reason_text'] || ge.message
271
+ else
272
+ error_message=ge #'' #ge.params.messages.message.text
273
+ end
274
+
275
+ og_logger.info("error happened in making the payment with creditcard: #{ge}")
276
+ result_xml='<?xml version="1.0" encoding="UTF-8"?><order><code>ERROR</code><errorCode>' + error_code + '</errorCode><errorMsg>' + error_message + '</errorMsg></order>'
277
+ end
278
+ else
279
+ errstr="The payment method should be CC"
280
+ og_logger.info("error happened in processing og order: #{errstr}")
281
+ result_xml='<?xml version="1.0" encoding="UTF-8"?><order><code>ERROR</code><errorCode>999</errorCode><errorMsg>' + errstr + '</errorMsg></order>'
282
+
283
+ #raise(errstr)
284
+ end
285
+
286
+ # 5. response xml with code and message
287
+ render :xml => result_xml #order.to_xml
288
+ end
289
+ end
290
+
291
+ end
292
+
293
+ end