solidus_volume_pricing 1.2.0 → 2.0.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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.git-blame-ignore-revs +3 -0
  3. data/.github/workflows/lint.yml +25 -0
  4. data/.github/workflows/test.yml +59 -0
  5. data/.rubocop.yml +0 -5
  6. data/Gemfile +21 -23
  7. data/Guardfile +8 -8
  8. data/README.md +1 -1
  9. data/Rakefile +3 -3
  10. data/app/models/solidus_volume_pricing/pricer.rb +9 -9
  11. data/app/models/solidus_volume_pricing/pricing_options.rb +2 -2
  12. data/app/models/spree/volume_price.rb +8 -8
  13. data/app/patches/helpers/solidus_volume_pricing/spree_base_helper_patch.rb +29 -0
  14. data/app/patches/models/solidus_volume_pricing/spree_line_item_patch.rb +18 -0
  15. data/app/patches/models/solidus_volume_pricing/spree_variant_patch.rb +21 -0
  16. data/bin/rails-engine +6 -6
  17. data/bin/rails-sandbox +4 -4
  18. data/config/routes.rb +1 -1
  19. data/db/migrate/20150603143015_create_spree_volume_price_models.rb +2 -2
  20. data/lib/generators/solidus_volume_pricing/install/install_generator.rb +4 -4
  21. data/lib/patches/backend/controllers/solidus_volume_pricing/spree_admin_variants_controller_patch.rb +38 -0
  22. data/lib/solidus_volume_pricing/engine.rb +22 -11
  23. data/lib/solidus_volume_pricing/range_from_string.rb +4 -4
  24. data/lib/solidus_volume_pricing/testing_support/factories.rb +5 -5
  25. data/lib/solidus_volume_pricing/version.rb +1 -1
  26. data/lib/solidus_volume_pricing.rb +9 -9
  27. data/solidus_volume_pricing.gemspec +20 -21
  28. metadata +41 -63
  29. data/.circleci/config.yml +0 -73
  30. data/.rubocop_todo.yml +0 -68
  31. data/app/decorators/controllers/solidus_volume_pricing/spree/admin/variants_controller_decorator.rb +0 -42
  32. data/app/decorators/helpers/solidus_volume_pricing/spree/base_helper_decorator.rb +0 -31
  33. data/app/decorators/models/solidus_volume_pricing/spree/line_item_decorator.rb +0 -18
  34. data/app/decorators/models/solidus_volume_pricing/spree/variant_decorator.rb +0 -23
  35. data/spec/controllers/spree/admin/variants_controller_spec.rb +0 -30
  36. data/spec/features/manage_volume_price_models_feature_spec.rb +0 -24
  37. data/spec/features/manage_volume_prices_feature_spec.rb +0 -33
  38. data/spec/helpers/base_helper_spec.rb +0 -24
  39. data/spec/lib/solidus_volume_pricing/range_from_string_spec.rb +0 -61
  40. data/spec/models/solidus_volume_pricing/pricer_spec.rb +0 -669
  41. data/spec/models/solidus_volume_pricing/pricing_options_spec.rb +0 -57
  42. data/spec/models/spree/line_item_spec.rb +0 -36
  43. data/spec/models/spree/order_spec.rb +0 -51
  44. data/spec/models/spree/variant_spec.rb +0 -6
  45. data/spec/models/spree/volume_price_spec.rb +0 -216
  46. data/spec/spec_helper.rb +0 -32
  47. data/spec/support/shoulda.rb +0 -11
@@ -1,669 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- RSpec.shared_examples 'having the variant price' do
6
- it 'uses the variants price' do
7
- expect(subject).to eq('$10.00')
8
- end
9
- end
10
-
11
- RSpec.describe SolidusVolumePricing::Pricer do
12
- let(:other_role) { create(:role) }
13
- let(:role) { create(:role) }
14
- let(:user) { create(:user) }
15
- let(:variant) { create(:variant, price: 10) }
16
-
17
- it 'inherits from default variant pricer' do
18
- expect(described_class < Spree::Variant::PriceSelector).to be(true)
19
- end
20
-
21
- it 'has SolidusVolumePricing::PricingOptions as pricing options class' do
22
- expect(described_class.pricing_options_class).to eq(SolidusVolumePricing::PricingOptions)
23
- end
24
-
25
- describe '#price_for' do
26
- subject do
27
- described_class.new(variant).price_for(pricing_options).to_s
28
- end
29
-
30
- let(:quantity) { 1 }
31
-
32
- let(:pricing_options) do
33
- SolidusVolumePricing::PricingOptions.new(quantity: quantity)
34
- end
35
-
36
- context 'discount_type = price' do
37
- before do
38
- variant.volume_prices.create!(amount: 7, discount_type: 'price', range: '(10+)')
39
- end
40
-
41
- context 'when quantity does not match the range' do
42
- it_behaves_like 'having the variant price'
43
- end
44
-
45
- context 'when quantity matches the range' do
46
- let(:quantity) { 10 }
47
-
48
- it 'uses the volume price' do
49
- expect(subject).to eq('$7.00')
50
- end
51
-
52
- context 'when volume price has a role' do
53
- before do
54
- variant.volume_prices.first.update(role_id: role.id)
55
- end
56
-
57
- context 'when no user is given' do
58
- it_behaves_like 'having the variant price'
59
- end
60
-
61
- context 'when a user is given' do
62
- let(:pricing_options) do
63
- SolidusVolumePricing::PricingOptions.new(
64
- quantity: quantity,
65
- user: user
66
- )
67
- end
68
-
69
- context 'whose role matches' do
70
- before { user.spree_roles << role }
71
-
72
- it 'uses the volume price' do
73
- expect(subject).to eq('$7.00')
74
- end
75
- end
76
-
77
- context 'whose role does not match' do
78
- before { user.spree_roles << other_role }
79
-
80
- it_behaves_like 'having the variant price'
81
- end
82
- end
83
- end
84
-
85
- context 'of a volume price model instead' do
86
- let(:quantity) { 6 }
87
-
88
- before do
89
- variant.volume_price_models << create(:volume_price_model)
90
- variant.volume_price_models.first.volume_prices.create!(amount: 5, discount_type: 'price', range: '(5+)')
91
- end
92
-
93
- it 'uses the volume price from model' do
94
- expect(subject).to eq('$5.00')
95
- end
96
- end
97
- end
98
- end
99
-
100
- context 'discount_type = dollar' do
101
- before do
102
- variant.volume_prices.create!(amount: 1, discount_type: 'dollar', range: '(10+)')
103
- end
104
-
105
- context 'when quantity does not match the range' do
106
- it_behaves_like 'having the variant price'
107
- end
108
-
109
- context 'when quantity matches the range' do
110
- let(:quantity) { 10 }
111
-
112
- it 'uses the volume price' do
113
- expect(subject).to eq('$9.00')
114
- end
115
-
116
- context 'when volume price has a role' do
117
- before do
118
- variant.volume_prices.first.update(role_id: role.id)
119
- end
120
-
121
- context 'when no user is given' do
122
- it_behaves_like 'having the variant price'
123
- end
124
-
125
- context 'when a user is given' do
126
- let(:pricing_options) do
127
- SolidusVolumePricing::PricingOptions.new(
128
- quantity: quantity,
129
- user: user
130
- )
131
- end
132
-
133
- context 'whose role matches' do
134
- before { user.spree_roles << role }
135
-
136
- it 'uses the volume price' do
137
- expect(subject).to eq('$9.00')
138
- end
139
- end
140
-
141
- context 'whose role does not match' do
142
- before { user.spree_roles << other_role }
143
-
144
- it_behaves_like 'having the variant price'
145
- end
146
- end
147
- end
148
- end
149
-
150
- context 'of a volume price model instead' do
151
- let(:quantity) { 6 }
152
-
153
- before do
154
- variant.volume_price_models << create(:volume_price_model)
155
- variant.volume_price_models.first.volume_prices.create!(amount: 2, discount_type: 'dollar', range: '(5+)')
156
- end
157
-
158
- it 'uses the volume price from model' do
159
- expect(subject).to eq('$8.00')
160
- end
161
- end
162
- end
163
-
164
- context 'discount_type = percent' do
165
- before do
166
- variant.volume_prices.create!(amount: 0.25, discount_type: 'percent', range: '(10+)')
167
- end
168
-
169
- context 'when quantity does not match the range' do
170
- it_behaves_like 'having the variant price'
171
- end
172
-
173
- context 'when quantity matches the range' do
174
- let(:quantity) { 10 }
175
-
176
- it 'uses the volume price' do
177
- expect(subject).to eq('$7.50')
178
- end
179
-
180
- context 'when volume price has a role' do
181
- before do
182
- variant.volume_prices.first.update(role_id: role.id)
183
- end
184
-
185
- context 'when no user is given' do
186
- it_behaves_like 'having the variant price'
187
- end
188
-
189
- context 'when a user is given' do
190
- let(:pricing_options) do
191
- SolidusVolumePricing::PricingOptions.new(
192
- quantity: quantity,
193
- user: user
194
- )
195
- end
196
-
197
- context 'whose role matches' do
198
- before { user.spree_roles << role }
199
-
200
- it 'uses the volume price' do
201
- expect(subject).to eq('$7.50')
202
- end
203
- end
204
-
205
- context 'whose role does not match' do
206
- before { user.spree_roles << other_role }
207
-
208
- it_behaves_like 'having the variant price'
209
- end
210
- end
211
- end
212
- end
213
-
214
- context 'of a volume price model instead' do
215
- let(:quantity) { 6 }
216
-
217
- it 'uses the volume price from model' do
218
- variant.volume_price_models << create(:volume_price_model)
219
- variant.volume_price_models.first.volume_prices.create!(amount: 0.75, discount_type: 'percent', range: '(5+)')
220
- expect(subject).to eq('$2.50')
221
- end
222
- end
223
- end
224
-
225
- context 'discount_type is unknown' do
226
- before do
227
- variant.volume_prices.create(amount: 7, discount_type: 'foo', range: '(10+)')
228
- end
229
-
230
- it_behaves_like 'having the variant price'
231
- end
232
-
233
- context 'when use_master_variant_volume_pricing' do
234
- let(:master) { variant.product.master }
235
-
236
- before do
237
- stub_spree_preferences(use_master_variant_volume_pricing: use_master_variant_volume_pricing)
238
- master.volume_prices.create!(amount: 1.5, discount_type: 'price', range: '(1+)')
239
- variant.volume_prices.create!(amount: 3.5, discount_type: 'price', range: '(1+)')
240
- end
241
-
242
- context 'is enabled' do
243
- let(:use_master_variant_volume_pricing) { true }
244
-
245
- context 'when volume prices are present on variant' do
246
- it 'uses the variant to compute price' do
247
- expect(subject).to eq('$3.50')
248
- end
249
- end
250
-
251
- context 'when no volume prices present on variant' do
252
- before do
253
- variant.volume_prices.delete_all
254
- end
255
-
256
- it 'uses the master variant to compute price' do
257
- expect(subject).to eq('$1.50')
258
- end
259
- end
260
- end
261
-
262
- context 'is disabled' do
263
- let(:use_master_variant_volume_pricing) { false }
264
-
265
- it 'uses the master variant to compute price' do
266
- expect(subject).to eq('$3.50')
267
- end
268
- end
269
- end
270
- end
271
-
272
- describe '#earning_amount' do
273
- subject do
274
- described_class.new(variant).earning_amount(pricing_options).to_s
275
- end
276
-
277
- let(:pricing_options) do
278
- SolidusVolumePricing::PricingOptions.new(quantity: quantity)
279
- end
280
-
281
- context 'discount_type = price' do
282
- before do
283
- variant.volume_prices.create!(amount: 9, discount_type: 'price', range: '(10+)')
284
- end
285
-
286
- context 'when quantity matches range' do
287
- let(:quantity) { 10 }
288
-
289
- it 'gives amount earning' do
290
- expect(subject).to eq('$1.00')
291
- end
292
-
293
- context 'when volume_price has role' do
294
- before do
295
- variant.volume_prices.first.update(role_id: role.id)
296
- end
297
-
298
- context 'when user is given' do
299
- let(:pricing_options) do
300
- SolidusVolumePricing::PricingOptions.new(
301
- quantity: quantity,
302
- user: user
303
- )
304
- end
305
-
306
- context 'whose role matches' do
307
- before do
308
- user.spree_roles << role
309
- end
310
-
311
- it 'gives amount earning' do
312
- expect(subject).to eq('$1.00')
313
- end
314
- end
315
-
316
- context 'whose role does not match' do
317
- before do
318
- user.spree_roles << other_role
319
- end
320
-
321
- it 'gives zero earning amount' do
322
- expect(subject).to eq('$0.00')
323
- end
324
- end
325
- end
326
-
327
- context 'when no user is given' do
328
- it 'gives zero earning amount' do
329
- expect(subject).to eq('$0.00')
330
- end
331
- end
332
- end
333
- end
334
-
335
- context 'when quantity does not match range' do
336
- let(:quantity) { 1 }
337
-
338
- it 'gives zero earning amount' do
339
- expect(subject).to eq('$0.00')
340
- end
341
- end
342
- end
343
-
344
- context 'discount_type = dollar' do
345
- before do
346
- variant.volume_prices.create!(amount: 2.5, discount_type: 'dollar', range: '(10+)')
347
- end
348
-
349
- context 'when amount matches range' do
350
- let(:quantity) { 10 }
351
-
352
- it 'gives amount earning' do
353
- expect(subject).to eq('$2.50')
354
- end
355
-
356
- context 'when volume_price has role' do
357
- before do
358
- variant.volume_prices.first.update(role_id: role.id)
359
- end
360
-
361
- context 'when user is given' do
362
- let(:pricing_options) do
363
- SolidusVolumePricing::PricingOptions.new(
364
- quantity: quantity,
365
- user: user
366
- )
367
- end
368
-
369
- context 'whose role matches' do
370
- before do
371
- user.spree_roles << role
372
- end
373
-
374
- it 'gives amount earning' do
375
- expect(subject).to eq('$2.50')
376
- end
377
- end
378
-
379
- context 'whose role does not match' do
380
- before do
381
- user.spree_roles << other_role
382
- end
383
-
384
- it 'gives zero earning amount' do
385
- expect(subject).to eq('$0.00')
386
- end
387
- end
388
- end
389
-
390
- context 'when no user is given' do
391
- it 'gives zero earning amount' do
392
- expect(subject).to eq('$0.00')
393
- end
394
- end
395
- end
396
- end
397
-
398
- context 'when amount does not match range' do
399
- let(:quantity) { 1 }
400
-
401
- it 'gives zero earning amount' do
402
- expect(subject).to eq('$0.00')
403
- end
404
- end
405
- end
406
-
407
- context 'discount_type = percent' do
408
- before do
409
- variant.volume_prices.create!(amount: 0.75, discount_type: 'percent', range: '(10+)')
410
- end
411
-
412
- context 'when amount matches range' do
413
- let(:quantity) { 10 }
414
-
415
- it 'gives amount earning' do
416
- expect(subject).to eq('$7.50')
417
- end
418
-
419
- context 'when volume_price has role' do
420
- before do
421
- variant.volume_prices.first.update(role_id: role.id)
422
- end
423
-
424
- context 'when user is given' do
425
- let(:pricing_options) do
426
- SolidusVolumePricing::PricingOptions.new(
427
- quantity: quantity,
428
- user: user
429
- )
430
- end
431
-
432
- context 'whose role matches' do
433
- before do
434
- user.spree_roles << role
435
- end
436
-
437
- it 'gives amount earning' do
438
- expect(subject).to eq('$7.50')
439
- end
440
- end
441
-
442
- context 'whose role does not match' do
443
- before do
444
- user.spree_roles << other_role
445
- end
446
-
447
- it 'gives zero earning amount' do
448
- expect(subject).to eq('$0.00')
449
- end
450
- end
451
- end
452
-
453
- context 'when no user is given' do
454
- it 'gives zero earning amount' do
455
- expect(subject).to eq('$0.00')
456
- end
457
- end
458
- end
459
- end
460
-
461
- context 'when amount does not match range' do
462
- let(:quantity) { 1 }
463
-
464
- it 'gives zero earning amount' do
465
- expect(subject).to eq('$0.00')
466
- end
467
- end
468
- end
469
- end
470
-
471
- describe '#earning_percent' do
472
- subject do
473
- described_class.new(variant).earning_percent(pricing_options)
474
- end
475
-
476
- let(:pricing_options) do
477
- SolidusVolumePricing::PricingOptions.new(quantity: quantity)
478
- end
479
-
480
- context 'discount_type = price' do
481
- before do
482
- variant.volume_prices.create!(amount: 9, discount_type: 'price', range: '(10+)')
483
- end
484
-
485
- context 'when quantity matches range' do
486
- let(:quantity) { 10 }
487
-
488
- it 'gives percent of earning' do
489
- expect(subject).to eq(10)
490
- end
491
-
492
- context 'when volume_price has role' do
493
- before do
494
- variant.volume_prices.first.update(role_id: role.id)
495
- end
496
-
497
- context 'when user is given' do
498
- let(:pricing_options) do
499
- SolidusVolumePricing::PricingOptions.new(
500
- quantity: quantity,
501
- user: user
502
- )
503
- end
504
-
505
- context 'whose role matches' do
506
- before do
507
- user.spree_roles << role
508
- end
509
-
510
- it 'gives percent of earning if role matches' do
511
- expect(subject).to eq(10)
512
- end
513
- end
514
-
515
- context 'whose role doesnt match' do
516
- before do
517
- user.spree_roles << other_role
518
- end
519
-
520
- it 'gives zero percent earning' do
521
- expect(subject).to eq(0)
522
- end
523
- end
524
- end
525
-
526
- context 'when no user is given' do
527
- it 'gives zero earning amount' do
528
- expect(subject).to eq(0)
529
- end
530
- end
531
- end
532
- end
533
-
534
- context 'when quantity does not match range' do
535
- let(:quantity) { 1 }
536
-
537
- it 'gives zero percent earning' do
538
- expect(subject).to eq(0)
539
- end
540
- end
541
- end
542
-
543
- context 'discount_type = dollar' do
544
- before do
545
- variant.volume_prices.create!(amount: 2.5, discount_type: 'dollar', range: '(10+)')
546
- end
547
-
548
- context 'when quantity matches range' do
549
- let(:quantity) { 10 }
550
-
551
- it 'gives percent of earning' do
552
- expect(subject).to eq(25)
553
- end
554
-
555
- context 'when volume_price has role' do
556
- before do
557
- variant.volume_prices.first.update(role_id: role.id)
558
- end
559
-
560
- context 'when user is given' do
561
- let(:pricing_options) do
562
- SolidusVolumePricing::PricingOptions.new(
563
- quantity: quantity,
564
- user: user
565
- )
566
- end
567
-
568
- context 'whose role matches' do
569
- before do
570
- user.spree_roles << role
571
- end
572
-
573
- it 'gives percent of earning if role matches' do
574
- expect(subject).to eq(25)
575
- end
576
- end
577
-
578
- context 'whose role doesnt match' do
579
- before do
580
- user.spree_roles << other_role
581
- end
582
-
583
- it 'gives zero percent earning' do
584
- expect(subject).to eq(0)
585
- end
586
- end
587
- end
588
-
589
- context 'when no user is given' do
590
- it 'gives zero earning amount' do
591
- expect(subject).to eq(0)
592
- end
593
- end
594
- end
595
- end
596
-
597
- context 'when quantity does not match range' do
598
- let(:quantity) { 1 }
599
-
600
- it 'gives zero percent earning' do
601
- expect(subject).to eq(0)
602
- end
603
- end
604
- end
605
-
606
- context 'discount_type = percent' do
607
- before do
608
- variant.volume_prices.create!(amount: 0.25, discount_type: 'percent', range: '(10+)')
609
- end
610
-
611
- context 'when quantity matches range' do
612
- let(:quantity) { 10 }
613
-
614
- it 'gives percent of earning' do
615
- expect(subject).to eq(25)
616
- end
617
-
618
- context 'when volume_price has role' do
619
- before do
620
- variant.volume_prices.first.update(role_id: role.id)
621
- end
622
-
623
- context 'when user is given' do
624
- let(:pricing_options) do
625
- SolidusVolumePricing::PricingOptions.new(
626
- quantity: quantity,
627
- user: user
628
- )
629
- end
630
-
631
- context 'whose role matches' do
632
- before do
633
- user.spree_roles << role
634
- end
635
-
636
- it 'gives percent of earning if role matches' do
637
- expect(subject).to eq(25)
638
- end
639
- end
640
-
641
- context 'whose role doesnt match' do
642
- before do
643
- user.spree_roles << other_role
644
- end
645
-
646
- it 'gives zero percent earning' do
647
- expect(subject).to eq(0)
648
- end
649
- end
650
- end
651
-
652
- context 'when no user is given' do
653
- it 'gives zero earning amount' do
654
- expect(subject).to eq(0)
655
- end
656
- end
657
- end
658
- end
659
-
660
- context 'when quantity does not match range' do
661
- let(:quantity) { 1 }
662
-
663
- it 'gives zero percent earning' do
664
- expect(subject).to eq(0)
665
- end
666
- end
667
- end
668
- end
669
- end
@@ -1,57 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- RSpec.describe SolidusVolumePricing::PricingOptions do
6
- let(:user) do
7
- build_stubbed(:user)
8
- end
9
-
10
- it 'inherits from default pricing options class' do
11
- expect(described_class < Spree::Variant::PricingOptions).to be(true)
12
- end
13
-
14
- describe 'new instances' do
15
- subject do
16
- described_class.new(quantity: 10, user: user)
17
- end
18
-
19
- it 'have a quantity attribute' do
20
- expect(subject.quantity).to eq(10)
21
- end
22
-
23
- it 'have a user attribute' do
24
- expect(subject.user).to eq(user)
25
- end
26
-
27
- it 'desired_attributes dont have quantity key' do
28
- expect(subject.desired_attributes).not_to have_key(:quantity)
29
- end
30
-
31
- it 'desired_attributes dont have user key' do
32
- expect(subject.desired_attributes).not_to have_key(:user)
33
- end
34
- end
35
-
36
- describe '.from_line_item' do
37
- subject do
38
- described_class.from_line_item(line_item)
39
- end
40
-
41
- let(:order) do
42
- build_stubbed(:order, user: user)
43
- end
44
-
45
- let(:line_item) do
46
- build_stubbed(:line_item, quantity: 2, order: order)
47
- end
48
-
49
- it 'sets quantity to quantity of line item' do
50
- expect(subject.quantity).to eq(2)
51
- end
52
-
53
- it 'sets user to user of line item' do
54
- expect(subject.user).to eq(user)
55
- end
56
- end
57
- end