mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-21 20:06:54 +00:00
Compare commits
230 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d7b130d293 | ||
|
|
617d914835 | ||
|
|
b1349306f9 | ||
|
|
9db9d2d138 | ||
|
|
bcbd1ce8bc | ||
|
|
370a108b3d | ||
|
|
38dde5e063 | ||
|
|
fe79186bec | ||
|
|
d5413224b7 | ||
|
|
90466e19dc | ||
|
|
acbe0faa1e | ||
|
|
1420c43a0a | ||
|
|
adf67475be | ||
|
|
c44ce85f30 | ||
|
|
46e6bc6179 | ||
|
|
e57acd3163 | ||
|
|
0878db70fe | ||
|
|
640681d664 | ||
|
|
b7e23a7401 | ||
|
|
863a7ec688 | ||
|
|
e9c789a459 | ||
|
|
3da21ce2bd | ||
|
|
d39468013e | ||
|
|
87bce505ec | ||
|
|
fb5668afa6 | ||
|
|
8f163cf5b5 | ||
|
|
b97734d918 | ||
|
|
0cfd7de8a8 | ||
|
|
d03be3b8dc | ||
|
|
e4d7e03903 | ||
|
|
899dffec96 | ||
|
|
818dfc0399 | ||
|
|
32761baa68 | ||
|
|
36380414a4 | ||
|
|
9791287712 | ||
|
|
4f7c8062a1 | ||
|
|
d502320b14 | ||
|
|
6fea2dbe46 | ||
|
|
45573dc522 | ||
|
|
0a1d4873e3 | ||
|
|
abe2cb9fac | ||
|
|
dcbe9c4011 | ||
|
|
d4f6f903c9 | ||
|
|
6cc19ac6d5 | ||
|
|
2668747237 | ||
|
|
57f429db58 | ||
|
|
de530c2a46 | ||
|
|
553053bad1 | ||
|
|
55cddbbc1a | ||
|
|
0a128d83d0 | ||
|
|
7cea4138c2 | ||
|
|
85c489d303 | ||
|
|
e6c59fbd96 | ||
|
|
3fddaba4bf | ||
|
|
0a88712926 | ||
|
|
4230d46a06 | ||
|
|
8a757812e7 | ||
|
|
f49355e5d3 | ||
|
|
12dac82b8a | ||
|
|
c604f4c0c6 | ||
|
|
bb21543ae0 | ||
|
|
c3897dd3df | ||
|
|
e6e20309aa | ||
|
|
9b1c0e6806 | ||
|
|
c5edd74d05 | ||
|
|
a6fba8a065 | ||
|
|
7525620d6c | ||
|
|
feca9e7838 | ||
|
|
398b4a09a1 | ||
|
|
366588de95 | ||
|
|
b5ab6cbf69 | ||
|
|
e762c1d02f | ||
|
|
f72cd6222f | ||
|
|
79316560d6 | ||
|
|
539ff228e0 | ||
|
|
afdb5e8c6f | ||
|
|
d40ec2d63c | ||
|
|
0d99656b1b | ||
|
|
52cfa0a103 | ||
|
|
d886b1dcea | ||
|
|
29e74017a6 | ||
|
|
9fe2cb1a30 | ||
|
|
0242e1a0c9 | ||
|
|
48c667d2dd | ||
|
|
06983c4dc7 | ||
|
|
0393e902c4 | ||
|
|
ab135e30c0 | ||
|
|
11fdbe5e9f | ||
|
|
34ae3ca24d | ||
|
|
f3da7afd55 | ||
|
|
dbef7b60a6 | ||
|
|
21f48b52c8 | ||
|
|
592474189d | ||
|
|
d52661fe0a | ||
|
|
00fcb89af1 | ||
|
|
dd4ca8a8e6 | ||
|
|
f25e06ddb6 | ||
|
|
3813b80615 | ||
|
|
88c21ef82e | ||
|
|
60c3557c2d | ||
|
|
6e7ee02191 | ||
|
|
e98d97ae0d | ||
|
|
10a60b1f72 | ||
|
|
686dcaaa1b | ||
|
|
5677c86f9b | ||
|
|
4a5869b60c | ||
|
|
efd2c81877 | ||
|
|
70bd81430d | ||
|
|
c5c9e803ab | ||
|
|
609db647bb | ||
|
|
0247386f82 | ||
|
|
1643636d43 | ||
|
|
d6a53cb84f | ||
|
|
94275eedfb | ||
|
|
59e900826e | ||
|
|
be9ee376a3 | ||
|
|
cc2e46890e | ||
|
|
46d23f1f8a | ||
|
|
4ab48c4b85 | ||
|
|
bd731267ec | ||
|
|
35b4e8c4d1 | ||
|
|
0166400b03 | ||
|
|
cf2a105b2a | ||
|
|
688be46b10 | ||
|
|
3558d01fce | ||
|
|
66423a1ec3 | ||
|
|
e5506df5ea | ||
|
|
af918e63ee | ||
|
|
7add9247d5 | ||
|
|
d5376ce29d | ||
|
|
84689c43be | ||
|
|
91d5b55376 | ||
|
|
0f92b3c4de | ||
|
|
0e7f4b2f14 | ||
|
|
d2b2e46124 | ||
|
|
3ef4a74b84 | ||
|
|
d8b795ebee | ||
|
|
70f30f5224 | ||
|
|
bba9e55006 | ||
|
|
ce4621858d | ||
|
|
8bcaeff6c8 | ||
|
|
1635b83c15 | ||
|
|
903b2e7ff4 | ||
|
|
ab5ffead1d | ||
|
|
affc82b2b5 | ||
|
|
d76db9ee51 | ||
|
|
d9b27bc556 | ||
|
|
5f1669280c | ||
|
|
b669ccdc74 | ||
|
|
84b5fcf2ce | ||
|
|
5c0408c68c | ||
|
|
8507dacc10 | ||
|
|
802e49bed3 | ||
|
|
40f9b063fe | ||
|
|
1833ab5ffa | ||
|
|
3370271ad8 | ||
|
|
b6e7307cb9 | ||
|
|
77419a1e4b | ||
|
|
e31d566f7f | ||
|
|
ca37976661 | ||
|
|
1d4fa2983c | ||
|
|
4a19a368dd | ||
|
|
dd38c8b3e2 | ||
|
|
cc9e3fe69b | ||
|
|
d9c065a311 | ||
|
|
996761da67 | ||
|
|
9bb49bb590 | ||
|
|
db23428832 | ||
|
|
783863056d | ||
|
|
d18e79ab19 | ||
|
|
e8ef4acb2b | ||
|
|
37b7340eb1 | ||
|
|
a124f93b20 | ||
|
|
20abaaa950 | ||
|
|
681a009eb6 | ||
|
|
caf1c9ecd9 | ||
|
|
e1c13bc194 | ||
|
|
ba018df9c5 | ||
|
|
a53cc6bc92 | ||
|
|
89ce850da6 | ||
|
|
b9cf5b7a9b | ||
|
|
012289e95f | ||
|
|
6a9505cf67 | ||
|
|
c4a8a38c8d | ||
|
|
a184075c5c | ||
|
|
b84fb5814e | ||
|
|
8b01c9c8ba | ||
|
|
79b86f535d | ||
|
|
8007554176 | ||
|
|
fc40775ca8 | ||
|
|
334e270a11 | ||
|
|
d1eea4654a | ||
|
|
d8436c2dab | ||
|
|
ea9ebc8a33 | ||
|
|
7c9024101b | ||
|
|
4060e7debf | ||
|
|
7a22367b4a | ||
|
|
23e6048bde | ||
|
|
ff8a81cee7 | ||
|
|
0eab1b2339 | ||
|
|
c0c7c6ec78 | ||
|
|
1eb08ba31c | ||
|
|
79668e06a7 | ||
|
|
8e4e276995 | ||
|
|
fd0bba19a7 | ||
|
|
ed0441dc41 | ||
|
|
19b12092a0 | ||
|
|
5d6d7f7ad0 | ||
|
|
96a351ad0e | ||
|
|
187b4a1fc2 | ||
|
|
8e65d29b02 | ||
|
|
c922a8fd4c | ||
|
|
f1618ec35f | ||
|
|
be229c9002 | ||
|
|
8c4d12a501 | ||
|
|
aacd942697 | ||
|
|
7d0ec48bcf | ||
|
|
e83a3ff76d | ||
|
|
ca4de40fa2 | ||
|
|
8399b82bfd | ||
|
|
26edd83a54 | ||
|
|
71dc5a8ff0 | ||
|
|
e34050f7cb | ||
|
|
544a7407e3 | ||
|
|
1b4254a5cf | ||
|
|
6f24ecd973 | ||
|
|
4d953abbe9 | ||
|
|
b02b36b8e8 | ||
|
|
776a61d1d9 | ||
|
|
5b9db50250 |
@@ -33,7 +33,6 @@ Layout/LineLength:
|
||||
- app/controllers/admin/product_import_controller.rb
|
||||
- app/controllers/admin/schedules_controller.rb
|
||||
- app/controllers/admin/subscriptions_controller.rb
|
||||
- app/controllers/admin/variant_overrides_controller.rb
|
||||
- app/controllers/api/enterprise_attachment_controller.rb
|
||||
- app/controllers/api/product_images_controller.rb
|
||||
- app/controllers/spree/paypal_controller_decorator.rb
|
||||
@@ -71,7 +70,6 @@ Layout/LineLength:
|
||||
- app/models/spree/variant.rb
|
||||
- app/models/subscription.rb
|
||||
- app/models/variant_override.rb
|
||||
- app/models/variant_override_set.rb
|
||||
- app/serializers/api/admin/subscription_line_item_serializer.rb
|
||||
- app/services/cart_service.rb
|
||||
- app/services/checkout/post_checkout_actions.rb
|
||||
@@ -254,7 +252,6 @@ Layout/LineLength:
|
||||
- spec/models/enterprise_relationship_spec.rb
|
||||
- spec/models/enterprise_spec.rb
|
||||
- spec/models/exchange_spec.rb
|
||||
- spec/models/model_set_spec.rb
|
||||
- spec/models/order_cycle_spec.rb
|
||||
- spec/models/product_importer_spec.rb
|
||||
- spec/models/product_import/reset_absent_spec.rb
|
||||
@@ -385,7 +382,6 @@ Metrics/AbcSize:
|
||||
- app/models/enterprise_group.rb
|
||||
- app/models/enterprise.rb
|
||||
- app/models/enterprise_relationship.rb
|
||||
- app/models/model_set.rb
|
||||
- app/models/product_import/entry_processor.rb
|
||||
- app/models/product_import/entry_validator.rb
|
||||
- app/models/product_import/product_importer.rb
|
||||
@@ -413,6 +409,7 @@ Metrics/AbcSize:
|
||||
- app/serializers/api/variant_serializer.rb
|
||||
- app/services/cart_service.rb
|
||||
- app/services/create_order_cycle.rb
|
||||
- app/services/sets/model_set.rb
|
||||
- app/services/order_cycle_form.rb
|
||||
- app/services/order_syncer.rb
|
||||
- app/services/variant_units/option_value_namer.rb
|
||||
@@ -538,8 +535,8 @@ Metrics/CyclomaticComplexity:
|
||||
- app/models/spree/product.rb
|
||||
- app/models/spree/return_authorization.rb
|
||||
- app/models/spree/zone.rb
|
||||
- app/models/variant_override_set.rb
|
||||
- app/services/cart_service.rb
|
||||
- app/services/sets/variant_override_set.rb
|
||||
- engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_report.rb
|
||||
- engines/order_management/app/services/order_management/stock/estimator.rb
|
||||
- lib/active_merchant/billing/gateways/stripe_payment_intents.rb
|
||||
|
||||
@@ -398,7 +398,6 @@ Style/ClassAndModuleChildren:
|
||||
- 'app/models/calculator/flat_percent_per_item.rb'
|
||||
- 'app/models/spree/gateway/migs.rb'
|
||||
- 'app/models/spree/gateway/pin.rb'
|
||||
- 'app/models/spree/product_set.rb'
|
||||
- 'app/models/tag_rule/discount_order.rb'
|
||||
- 'app/models/tag_rule/filter_order_cycles.rb'
|
||||
- 'app/models/tag_rule/filter_payment_methods.rb'
|
||||
@@ -575,7 +574,6 @@ Style/FrozenStringLiteralComment:
|
||||
- 'app/models/calculator/flat_percent_per_item.rb'
|
||||
- 'app/models/calculator/weight.rb'
|
||||
- 'app/models/column_preference.rb'
|
||||
- 'app/models/column_preference_set.rb'
|
||||
- 'app/models/concerns/address_display.rb'
|
||||
- 'app/models/concerns/adjustment_scopes.rb'
|
||||
- 'app/models/concerns/line_item_based_adjustment_handling.rb'
|
||||
@@ -588,17 +586,13 @@ Style/FrozenStringLiteralComment:
|
||||
- 'app/models/customer.rb'
|
||||
- 'app/models/distributor_shipping_method.rb'
|
||||
- 'app/models/enterprise_fee.rb'
|
||||
- 'app/models/enterprise_fee_set.rb'
|
||||
- 'app/models/enterprise_relationship_permission.rb'
|
||||
- 'app/models/enterprise_role.rb'
|
||||
- 'app/models/enterprise_set.rb'
|
||||
- 'app/models/exchange.rb'
|
||||
- 'app/models/exchange_fee.rb'
|
||||
- 'app/models/exchange_variant.rb'
|
||||
- 'app/models/inventory_item.rb'
|
||||
- 'app/models/model_set.rb'
|
||||
- 'app/models/order_cycle.rb'
|
||||
- 'app/models/order_cycle_set.rb'
|
||||
- 'app/models/preference_sections/footer_and_external_links_section.rb'
|
||||
- 'app/models/preference_sections/group_signup_page_section.rb'
|
||||
- 'app/models/preference_sections/header_section.rb'
|
||||
@@ -623,7 +617,6 @@ Style/FrozenStringLiteralComment:
|
||||
- 'app/models/spree/gateway/pin.rb'
|
||||
- 'app/models/spree/gateway/stripe_connect.rb'
|
||||
- 'app/models/spree/preferences/file_configuration.rb'
|
||||
- 'app/models/spree/product_set.rb'
|
||||
- 'app/models/spree/property.rb'
|
||||
- 'app/models/spree/user.rb'
|
||||
- 'app/models/stripe_account.rb'
|
||||
@@ -636,7 +629,6 @@ Style/FrozenStringLiteralComment:
|
||||
- 'app/models/tag_rule/filter_products.rb'
|
||||
- 'app/models/tag_rule/filter_shipping_methods.rb'
|
||||
- 'app/models/variant_override.rb'
|
||||
- 'app/models/variant_override_set.rb'
|
||||
- 'app/serializers/api/address_serializer.rb'
|
||||
- 'app/serializers/api/adjustment_serializer.rb'
|
||||
- 'app/serializers/api/cached_enterprise_serializer.rb'
|
||||
|
||||
11
Gemfile
11
Gemfile
@@ -21,6 +21,7 @@ if ENV['DEPENDENCIES_NEXT']
|
||||
gem 'responders'
|
||||
gem 'sass', '<= 4.7.1'
|
||||
gem 'sass-rails', '< 6.0.0'
|
||||
gem 'libv8', '< 8'
|
||||
else
|
||||
gem 'rails', '~> 4.2'
|
||||
|
||||
@@ -34,6 +35,10 @@ else
|
||||
|
||||
gem 'db2fog'
|
||||
gem 'unicorn'
|
||||
|
||||
group :test do
|
||||
gem 'test_after_commit' # needed to test Devise callbacks
|
||||
end
|
||||
end
|
||||
|
||||
gem 'i18n'
|
||||
@@ -56,12 +61,12 @@ gem 'cancancan', '~> 1.7.0'
|
||||
gem 'ffaker'
|
||||
gem 'highline', '2.0.3' # Necessary for the install generator
|
||||
gem 'json'
|
||||
gem 'monetize', '~> 1.1'
|
||||
gem 'monetize', '~> 1.10'
|
||||
gem 'paranoia', '~> 2.4'
|
||||
gem 'state_machines-activerecord'
|
||||
gem 'stringex', '~> 2.8.5'
|
||||
|
||||
gem 'paypal-sdk-merchant', '1.106.1'
|
||||
gem 'paypal-sdk-merchant', '1.117.2'
|
||||
gem 'stripe'
|
||||
|
||||
gem 'devise'
|
||||
@@ -119,6 +124,7 @@ gem 'mini_racer', '0.2.15'
|
||||
|
||||
gem 'uglifier', '>= 1.0.3'
|
||||
|
||||
gem 'angular_rails_csrf'
|
||||
gem 'foundation-icons-sass-rails'
|
||||
|
||||
gem 'foundation-rails', '= 5.5.2.1'
|
||||
@@ -159,7 +165,6 @@ end
|
||||
group :test do
|
||||
gem 'simplecov', require: false
|
||||
gem 'test-prof'
|
||||
gem 'test_after_commit' # needed to test Devise callbacks
|
||||
gem 'webmock'
|
||||
# See spec/spec_helper.rb for instructions
|
||||
# gem 'perftools.rb'
|
||||
|
||||
57
Gemfile.lock
57
Gemfile.lock
@@ -105,10 +105,12 @@ GEM
|
||||
railties (>= 3.1)
|
||||
sprockets (~> 2.0)
|
||||
tilt
|
||||
angular_rails_csrf (4.2.0)
|
||||
railties (>= 3, < 7)
|
||||
angularjs-file-upload-rails (2.4.1)
|
||||
angularjs-rails (1.5.5)
|
||||
arel (6.0.4)
|
||||
ast (2.4.1)
|
||||
ast (2.4.2)
|
||||
atomic (1.1.101)
|
||||
awesome_nested_set (3.3.1)
|
||||
activerecord (>= 4.0.0, < 7.0)
|
||||
@@ -164,7 +166,7 @@ GEM
|
||||
compass (~> 1.0.0)
|
||||
sass-rails (< 5.1)
|
||||
sprockets (< 4.0)
|
||||
concurrent-ruby (1.1.7)
|
||||
concurrent-ruby (1.1.8)
|
||||
crack (0.4.5)
|
||||
rexml
|
||||
crass (1.0.6)
|
||||
@@ -172,12 +174,12 @@ GEM
|
||||
addressable
|
||||
daemons (1.3.1)
|
||||
dalli (2.7.11)
|
||||
database_cleaner (1.8.5)
|
||||
database_cleaner (1.99.0)
|
||||
db2fog (0.9.0)
|
||||
activerecord (>= 3.2.0, < 5.0)
|
||||
fog (~> 1.0)
|
||||
rails (>= 3.2.0, < 5.0)
|
||||
ddtrace (0.44.0)
|
||||
ddtrace (0.45.0)
|
||||
msgpack
|
||||
debugger-linecache (1.2.0)
|
||||
delayed_job (4.1.9)
|
||||
@@ -436,7 +438,7 @@ GEM
|
||||
letter_opener (1.7.0)
|
||||
launchy (~> 2.2)
|
||||
libv8 (7.3.492.27.1)
|
||||
loofah (2.8.0)
|
||||
loofah (2.9.0)
|
||||
crass (~> 1.0.2)
|
||||
nokogiri (>= 1.5.9)
|
||||
mail (2.7.1)
|
||||
@@ -450,11 +452,11 @@ GEM
|
||||
mini_racer (0.2.15)
|
||||
libv8 (> 7.3)
|
||||
minitest (5.14.3)
|
||||
monetize (1.9.4)
|
||||
monetize (1.10.0)
|
||||
money (~> 6.12)
|
||||
money (6.13.8)
|
||||
money (6.14.0)
|
||||
i18n (>= 0.6.4, <= 2)
|
||||
msgpack (1.3.3)
|
||||
msgpack (1.4.2)
|
||||
multi_json (1.15.0)
|
||||
multi_xml (0.6.0)
|
||||
multipart-post (2.1.1)
|
||||
@@ -483,11 +485,11 @@ GEM
|
||||
activerecord (>= 4.0, < 6.2)
|
||||
parser (3.0.0.0)
|
||||
ast (~> 2.4.1)
|
||||
paypal-sdk-core (0.2.10)
|
||||
paypal-sdk-core (0.3.4)
|
||||
multi_json (~> 1.0)
|
||||
xml-simple
|
||||
paypal-sdk-merchant (1.106.1)
|
||||
paypal-sdk-core (~> 0.2.3)
|
||||
paypal-sdk-merchant (1.117.2)
|
||||
paypal-sdk-core (~> 0.3.0)
|
||||
pg (0.21.0)
|
||||
power_assert (1.2.0)
|
||||
pry (0.13.1)
|
||||
@@ -498,7 +500,7 @@ GEM
|
||||
pry (~> 0.13.0)
|
||||
public_suffix (4.0.6)
|
||||
rack (1.6.13)
|
||||
rack-mini-profiler (2.3.0)
|
||||
rack-mini-profiler (2.3.1)
|
||||
rack (>= 1.2.0)
|
||||
rack-protection (1.5.5)
|
||||
rack
|
||||
@@ -596,20 +598,20 @@ GEM
|
||||
rspec-retry (0.6.2)
|
||||
rspec-core (> 3.3)
|
||||
rspec-support (3.10.1)
|
||||
rswag (2.3.1)
|
||||
rswag-api (= 2.3.1)
|
||||
rswag-specs (= 2.3.1)
|
||||
rswag-ui (= 2.3.1)
|
||||
rswag-api (2.3.1)
|
||||
rswag (2.3.2)
|
||||
rswag-api (= 2.3.2)
|
||||
rswag-specs (= 2.3.2)
|
||||
rswag-ui (= 2.3.2)
|
||||
rswag-api (2.3.2)
|
||||
railties (>= 3.1, < 7.0)
|
||||
rswag-specs (2.3.1)
|
||||
rswag-specs (2.3.2)
|
||||
activesupport (>= 3.1, < 7.0)
|
||||
json-schema (~> 2.2)
|
||||
railties (>= 3.1, < 7.0)
|
||||
rswag-ui (2.3.1)
|
||||
rswag-ui (2.3.2)
|
||||
actionpack (>= 3.1, < 7.0)
|
||||
railties (>= 3.1, < 7.0)
|
||||
rubocop (1.8.1)
|
||||
rubocop (1.9.0)
|
||||
parallel (~> 1.10)
|
||||
parser (>= 3.0.0.0)
|
||||
rainbow (>= 2.2.2, < 4.0)
|
||||
@@ -618,7 +620,7 @@ GEM
|
||||
rubocop-ast (>= 1.2.0, < 2.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (>= 1.4.0, < 3.0)
|
||||
rubocop-ast (1.4.0)
|
||||
rubocop-ast (1.4.1)
|
||||
parser (>= 2.7.1.5)
|
||||
rubocop-rails (2.9.1)
|
||||
activesupport (>= 4.2.0)
|
||||
@@ -640,7 +642,7 @@ GEM
|
||||
selenium-webdriver (3.142.7)
|
||||
childprocess (>= 0.5, < 4.0)
|
||||
rubyzip (>= 1.2.2)
|
||||
shoulda-matchers (4.5.0)
|
||||
shoulda-matchers (4.5.1)
|
||||
activesupport (>= 4.2.0)
|
||||
simplecov (0.18.5)
|
||||
docile (~> 1.1)
|
||||
@@ -700,11 +702,11 @@ GEM
|
||||
unicorn (>= 4, < 6)
|
||||
warden (1.2.7)
|
||||
rack (>= 1.0)
|
||||
webdrivers (4.4.2)
|
||||
webdrivers (4.5.0)
|
||||
nokogiri (~> 1.6)
|
||||
rubyzip (>= 1.3.0)
|
||||
selenium-webdriver (>= 3.0, < 4.0)
|
||||
webmock (3.11.1)
|
||||
webmock (3.11.2)
|
||||
addressable (>= 2.3.6)
|
||||
crack (>= 0.3.2)
|
||||
hashdiff (>= 0.4.0, < 2.0.0)
|
||||
@@ -713,7 +715,7 @@ GEM
|
||||
wicked_pdf (2.1.0)
|
||||
activesupport
|
||||
wkhtmltopdf-binary (0.12.5)
|
||||
xml-simple (1.1.5)
|
||||
xml-simple (1.1.8)
|
||||
xmlrpc (0.3.0)
|
||||
xpath (3.2.0)
|
||||
nokogiri (~> 1.8)
|
||||
@@ -732,6 +734,7 @@ DEPENDENCIES
|
||||
acts_as_list (= 0.9.19)
|
||||
andand
|
||||
angular-rails-templates (~> 0.3.0)
|
||||
angular_rails_csrf
|
||||
angularjs-file-upload-rails (~> 2.4.1)
|
||||
angularjs-rails (= 1.5.5)
|
||||
atomic
|
||||
@@ -783,14 +786,14 @@ DEPENDENCIES
|
||||
knapsack
|
||||
letter_opener (>= 1.4.1)
|
||||
mini_racer (= 0.2.15)
|
||||
monetize (~> 1.1)
|
||||
monetize (~> 1.10)
|
||||
oauth2 (~> 1.4.4)
|
||||
ofn-qz!
|
||||
order_management!
|
||||
paper_trail (~> 10.3.1)
|
||||
paperclip (~> 3.4.1)
|
||||
paranoia (~> 2.4)
|
||||
paypal-sdk-merchant (= 1.106.1)
|
||||
paypal-sdk-merchant (= 1.117.2)
|
||||
pg (~> 0.21.0)
|
||||
pry
|
||||
pry-byebug
|
||||
|
||||
@@ -104,6 +104,8 @@ GEM
|
||||
railties (>= 4.2, < 7)
|
||||
sprockets (>= 3.0, < 5)
|
||||
tilt
|
||||
angular_rails_csrf (4.2.0)
|
||||
railties (>= 3, < 7)
|
||||
angularjs-file-upload-rails (2.4.1)
|
||||
angularjs-rails (1.5.5)
|
||||
arel (7.1.4)
|
||||
@@ -268,7 +270,7 @@ GEM
|
||||
addressable (~> 2.3)
|
||||
letter_opener (1.7.0)
|
||||
launchy (~> 2.2)
|
||||
libv8 (8.4.255.0)
|
||||
libv8 (7.3.492.27.1)
|
||||
loofah (2.7.0)
|
||||
crass (~> 1.0.2)
|
||||
nokogiri (>= 1.5.9)
|
||||
@@ -500,8 +502,6 @@ GEM
|
||||
test-prof (0.7.5)
|
||||
test-unit (3.3.7)
|
||||
power_assert
|
||||
test_after_commit (1.1.0)
|
||||
activerecord (>= 3.2)
|
||||
thor (0.20.3)
|
||||
thread_safe (0.3.6)
|
||||
tilt (2.0.10)
|
||||
@@ -556,6 +556,7 @@ DEPENDENCIES
|
||||
acts_as_list (= 0.9.19)
|
||||
andand
|
||||
angular-rails-templates (>= 0.3.0)
|
||||
angular_rails_csrf
|
||||
angularjs-file-upload-rails (~> 2.4.1)
|
||||
angularjs-rails (= 1.5.5)
|
||||
atomic
|
||||
@@ -605,6 +606,7 @@ DEPENDENCIES
|
||||
kaminari (~> 1.2.1)
|
||||
knapsack
|
||||
letter_opener (>= 1.4.1)
|
||||
libv8 (< 8)
|
||||
mini_racer (= 0.2.15)
|
||||
monetize (~> 1.1)
|
||||
oauth2 (~> 1.4.4)
|
||||
@@ -646,7 +648,6 @@ DEPENDENCIES
|
||||
stripe
|
||||
test-prof
|
||||
test-unit (~> 3.3)
|
||||
test_after_commit
|
||||
timecop
|
||||
uglifier (>= 1.0.3)
|
||||
unicorn-rails
|
||||
|
||||
@@ -10,5 +10,4 @@ angular.module("ofn.admin", [
|
||||
"admin.taxons",
|
||||
"infinite-scroll"
|
||||
]).config ($httpProvider) ->
|
||||
$httpProvider.defaults.headers.common["X-CSRF-Token"] = $("meta[name=csrf-token]").attr("content")
|
||||
$httpProvider.defaults.headers.common["Accept"] = "application/json, text/javascript, */*"
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
//= require jquery.cookie
|
||||
//= require jquery.jstree/jquery.jstree
|
||||
//= require jquery.vAlign
|
||||
//= require jquery.horizontalNav
|
||||
//= require jquery.adaptivemenu
|
||||
//= require angular
|
||||
//= require angular-resource
|
||||
//= require angular-animate
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
angular.module("admin.indexUtils", ['admin.resources', 'ngSanitize', 'templates', 'admin.utils']).config ($httpProvider) ->
|
||||
$httpProvider.defaults.headers.common["X-CSRF-Token"] = $("meta[name=csrf-token]").attr("content");
|
||||
$httpProvider.defaults.headers.common["Accept"] = "application/json, text/javascript, */*"
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
angular.module('admin.orderCycles', ['ngTagsInput', 'admin.indexUtils', 'admin.enterprises'])
|
||||
|
||||
.config ($httpProvider) ->
|
||||
$httpProvider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content')
|
||||
|
||||
.directive 'datetimepicker', ($timeout, $parse) ->
|
||||
require: "ngModel"
|
||||
link: (scope, element, attrs, ngModel) ->
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
angular.module("admin.productImport", ["ngResource"]).config ($httpProvider) ->
|
||||
$httpProvider.defaults.headers.common["X-CSRF-Token"] = $("meta[name=csrf-token]").attr("content")
|
||||
$httpProvider.defaults.headers.common["Accept"] = "application/json, text/javascript, */*"
|
||||
|
||||
@@ -8,27 +8,10 @@ Hopefully, this will evolve into a propper class.
|
||||
**/
|
||||
|
||||
jQuery(function($) {
|
||||
// Make main menu use full width
|
||||
mainMenu = $('.fullwidth-menu')
|
||||
if (typeof mainMenu.horizontalNav === 'function' )
|
||||
mainMenu.horizontalNav({
|
||||
tableDisplay: false,
|
||||
responsiveDelay: 0
|
||||
});
|
||||
|
||||
// Vertical align of checkbox fields
|
||||
if (typeof $('.field.checkbox label').vAlign === 'function' )
|
||||
$('.field.checkbox label').vAlign()
|
||||
|
||||
// We activate AdaptiveMenu only if not on webdriver
|
||||
// Re-adjusting the admin menu during tests causes tests to fail.
|
||||
if (!navigator.webdriver && typeof Spree !== 'undefined') {
|
||||
$('.main-menu-wrapper ul').AdaptiveMenu({
|
||||
text: "<a href='#'><i class='icon-chevron-down'></i> " + Spree.translations.more + "</a>",
|
||||
klass: "dropdown"
|
||||
});
|
||||
}
|
||||
|
||||
// Add some tips
|
||||
if (typeof $('.with-tip').powerTip === 'function' ) {
|
||||
$('.with-tip').powerTip({
|
||||
|
||||
@@ -40,7 +40,13 @@ $(document).ready(function() {
|
||||
var variant_id = save.data('variant-id');
|
||||
|
||||
var quantity = parseInt(save.parents('tr').find('input.line_item_quantity').val());
|
||||
var maxQuantity = parseInt(save.parents('tr').find('input.line_item_quantity').attr("max"));
|
||||
|
||||
if (quantity > maxQuantity) {
|
||||
quantity = maxQuantity;
|
||||
save.parents('tr').find('input.line_item_quantity').val(maxQuantity);
|
||||
alert(t("js.admin.orders.quantity_adjusted"));
|
||||
}
|
||||
toggleItemEdit();
|
||||
|
||||
adjustItems(shipment_number, variant_id, quantity);
|
||||
@@ -77,7 +83,9 @@ adjustItems = function(shipment_number, variant_id, quantity){
|
||||
}
|
||||
url += '.json';
|
||||
|
||||
if(new_quantity!=0){
|
||||
if (new_quantity == 0) {
|
||||
alert(t("js.admin.orders.quantity_unchanged"));
|
||||
} else {
|
||||
$.ajax({
|
||||
type: "PUT",
|
||||
url: Spree.url(url),
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
angular.module("admin.utils", ["templates", "ngSanitize"]).config ($httpProvider) ->
|
||||
angular.module("admin.utils", ["templates", "ngSanitize"]).config ($httpProvider) ->
|
||||
$httpProvider.defaults.headers.common["Accept"] = "application/json, text/javascript, */*"
|
||||
|
||||
@@ -6,28 +6,62 @@ Darkswarm.controller "ShopVariantCtrl", ($scope, $modal, Cart) ->
|
||||
return if old_value[0] == null && new_value[0] == null
|
||||
Cart.adjust($scope.variant.line_item)
|
||||
|
||||
$scope.add = (quantity) ->
|
||||
$scope.variant.line_item.quantity ||= 0
|
||||
|
||||
$scope.$watch "variant.line_item.quantity", ->
|
||||
item = $scope.variant.line_item
|
||||
item.quantity += quantity
|
||||
if $scope.variant.product.group_buy
|
||||
if item.quantity > $scope.available()
|
||||
item.quantity = $scope.available()
|
||||
|
||||
$scope.$watch "variant.line_item.max_quantity", ->
|
||||
item = $scope.variant.line_item
|
||||
if item.max_quantity > $scope.available()
|
||||
item.max_quantity = $scope.available()
|
||||
|
||||
if $scope.variant.product.group_buy
|
||||
$scope.$watch "variant.line_item.quantity", ->
|
||||
item = $scope.variant.line_item
|
||||
if item.quantity < 1 || item.max_quantity < item.quantity
|
||||
item.max_quantity = item.quantity
|
||||
|
||||
$scope.$watch "variant.line_item.max_quantity", ->
|
||||
item = $scope.variant.line_item
|
||||
if item.max_quantity < item.quantity
|
||||
item.quantity = item.max_quantity
|
||||
|
||||
$scope.quantity = ->
|
||||
$scope.variant.line_item.quantity || 0
|
||||
|
||||
$scope.maxQuantity = ->
|
||||
$scope.variant.line_item.max_quantity || $scope.sanitizedQuantity()
|
||||
|
||||
$scope.sanitizedQuantity = ->
|
||||
Math.max(0, Math.min($scope.quantity(), $scope.available()))
|
||||
|
||||
$scope.sanitizedMaxQuantity = ->
|
||||
Math.max($scope.sanitizedQuantity(), Math.min($scope.maxQuantity(), $scope.available()))
|
||||
|
||||
$scope.add = (quantity) ->
|
||||
item = $scope.variant.line_item
|
||||
item.quantity = $scope.sanitizedQuantity() + quantity
|
||||
|
||||
$scope.addMax = (quantity) ->
|
||||
item = $scope.variant.line_item
|
||||
item.max_quantity += quantity
|
||||
if item.max_quantity < item.quantity
|
||||
item.quantity = item.max_quantity
|
||||
item.max_quantity = $scope.sanitizedMaxQuantity() + quantity
|
||||
|
||||
$scope.canAdd = (quantity) ->
|
||||
wantedQuantity = $scope.variant.line_item.quantity + quantity
|
||||
wantedQuantity = $scope.sanitizedQuantity() + quantity
|
||||
$scope.quantityValid(wantedQuantity)
|
||||
|
||||
$scope.canAddMax = (quantity) ->
|
||||
variant = $scope.variant
|
||||
wantedQuantity = variant.line_item.max_quantity + quantity
|
||||
wantedQuantity = $scope.sanitizedMaxQuantity() + quantity
|
||||
$scope.quantityValid(wantedQuantity) && variant.line_item.quantity > 0
|
||||
|
||||
$scope.available = ->
|
||||
variant = $scope.variant
|
||||
variant.on_demand && Infinity || variant.on_hand
|
||||
|
||||
$scope.quantityValid = (quantity) ->
|
||||
variant = $scope.variant
|
||||
minimum = 0
|
||||
|
||||
@@ -12,7 +12,6 @@ window.Darkswarm = angular.module("Darkswarm", [
|
||||
'angularFileUpload',
|
||||
'angularSlideables'
|
||||
]).config ($httpProvider, $tooltipProvider, $locationProvider, $anchorScrollProvider) ->
|
||||
$httpProvider.defaults.headers['common']['X-CSRF-Token'] = $('meta[name="csrf-token"]').attr('content')
|
||||
$httpProvider.defaults.headers['common']['X-Requested-With'] = 'XMLHttpRequest'
|
||||
$httpProvider.defaults.headers.common.Accept = "application/json, text/javascript, */*"
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Darkswarm.directive "tabsetCtrl", (Tabsets, $location) ->
|
||||
Darkswarm.directive "tabsetCtrl", (Tabsets, $location, $rootScope) ->
|
||||
restrict: "C"
|
||||
scope:
|
||||
id: "@"
|
||||
@@ -9,7 +9,13 @@ Darkswarm.directive "tabsetCtrl", (Tabsets, $location) ->
|
||||
if $scope.navigate
|
||||
path = $location.path()?.match(/^\/\w+$/)?[0]
|
||||
$scope.selected = path[1..] if path
|
||||
|
||||
|
||||
# Watch location change success event to operate back/forward buttons
|
||||
$rootScope.$on "$locationChangeSuccess", ->
|
||||
if $scope.navigate
|
||||
path = $location.path()?.match(/^\/\w+$/)?[0]
|
||||
Tabsets.toggle($scope.id, path[1..] if path)
|
||||
|
||||
this.toggle = (name) ->
|
||||
Tabsets.toggle($scope.id, name)
|
||||
|
||||
|
||||
@@ -23,5 +23,5 @@ Darkswarm.factory 'Variants', ->
|
||||
|
||||
lineItemFor: (variant) ->
|
||||
variant: variant
|
||||
quantity: null
|
||||
max_quantity: null
|
||||
quantity: 0
|
||||
max_quantity: 0
|
||||
|
||||
@@ -9,27 +9,33 @@
|
||||
{{ variant.line_item.total_price | localizeCurrency }}
|
||||
|
||||
.row
|
||||
.columns.small-6
|
||||
.columns.small-12.medium-6
|
||||
.variant-bulk-buy-quantity-label
|
||||
{{ "js.shopfront.bulk_buy_modal.min_quantity" | t }}
|
||||
%div
|
||||
%button.bulk-buy-add.variant-quantity{type: "button", ng: {click: "add(-1)", disabled: "!canAdd(-1)"}}>
|
||||
-# U+FF0D Fullwidth Hyphen-Minus
|
||||
-
|
||||
%span.bulk-buy.variant-quantity>
|
||||
{{ variant.line_item.quantity }}
|
||||
%input.bulk-buy.variant-quantity{
|
||||
type: "number",
|
||||
min: "0",
|
||||
max: "{{ available() }}",
|
||||
ng: {model: "variant.line_item.quantity", max: "Infinity"}}>
|
||||
%button.bulk-buy-add.variant-quantity{type: "button", ng: {click: "add(1)", disabled: "!canAdd(1)"}}
|
||||
-# U+FF0B Fullwidth Plus Sign
|
||||
+
|
||||
.columns.small-6
|
||||
.columns.small-12.medium-6
|
||||
.variant-bulk-buy-quantity-label
|
||||
{{ "js.shopfront.bulk_buy_modal.max_quantity" | t }}
|
||||
%div
|
||||
%button.bulk-buy-add.variant-quantity{type: "button", ng: {click: "addMax(-1)", disabled: "!canAddMax(-1)"}}>
|
||||
-# U+FF0D Fullwidth Hyphen-Minus
|
||||
-
|
||||
%span.bulk-buy.variant-quantity>
|
||||
{{ variant.line_item.max_quantity }}
|
||||
%input.bulk-buy.variant-quantity{
|
||||
type: "number",
|
||||
min: "0",
|
||||
max: "{{ available() }}",
|
||||
ng: {model: "variant.line_item.max_quantity", max: "Infinity"}}>
|
||||
%button.bulk-buy-add.variant-quantity{type: "button", ng: {click: "addMax(1)", disabled: "!canAddMax(1)"}}
|
||||
-# U+FF0B Fullwidth Plus Sign
|
||||
+
|
||||
|
||||
@@ -1,14 +1,22 @@
|
||||
.small-5.medium-3.large-3.columns.text-right{"ng-if" => "::!variant.product.group_buy"}
|
||||
.small-5.medium-3.large-3.columns.variant-quantity-column.text-right{"ng-if" => "::!variant.product.group_buy"}
|
||||
|
||||
%button.add-variant{type: "button", ng: {if: "!variant.line_item.quantity", click: "add(1)", disabled: "!canAdd(1)"}}
|
||||
{{ "js.shopfront.variant.add_to_cart" | t }}
|
||||
%button.variant-quantity{type: "button", ng: {if: "variant.line_item.quantity", click: "add(-1)"}}>
|
||||
-# U+FF0D Fullwidth Hyphen-Minus
|
||||
-
|
||||
%button.variant-quantity{type: "button", ng: {if: "variant.line_item.quantity", click: "add(1)", disabled: "!canAdd(1)"}}
|
||||
-# U+FF0B Fullwidth Plus Sign
|
||||
+
|
||||
%br
|
||||
.variant-quantity-inputs{ng: {if: "variant.line_item.quantity == 0"}}
|
||||
%button.add-variant{type: "button", ng: {click: "add(1)", disabled: "!canAdd(1)"}}
|
||||
{{ "js.shopfront.variant.add_to_cart" | t }}
|
||||
|
||||
.variant-quantity-inputs{ng: {if: "variant.line_item.quantity != 0"}}
|
||||
%button.variant-quantity{type: "button", ng: {click: "add(-1)", disabled: "!canAdd(-1)"}}>
|
||||
-# U+FF0D Fullwidth Hyphen-Minus
|
||||
-
|
||||
%input.variant-quantity{
|
||||
type: "number",
|
||||
min: "0",
|
||||
max: "{{ available() }}",
|
||||
ng: {model: "variant.line_item.quantity", max: "Infinity"}
|
||||
}>
|
||||
%button.variant-quantity{type: "button", ng: {click: "add(1)", disabled: "!canAdd(1)"}}
|
||||
-# U+FF0B Fullwidth Plus Sign
|
||||
+
|
||||
.variant-quantity-display{ng: {class: "{visible: variant.line_item.quantity}"}}
|
||||
{{ "js.shopfront.variant.quantity_in_cart" | t:{quantity: variant.line_item.quantity || 0} }}
|
||||
%input{type: :hidden,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.small-5.medium-3.large-3.columns.text-right{"ng-if" => "::variant.product.group_buy"}
|
||||
.small-5.medium-3.large-3.columns.variant-quantity-column.text-right{"ng-if" => "::variant.product.group_buy"}
|
||||
|
||||
%button.add-variant{type: "button", ng: {if: "!variant.line_item.quantity", click: "addBulk(1)", disabled: "!canAdd(1)"}}
|
||||
{{ "js.shopfront.variant.add_to_cart" | t }}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
.variants.row
|
||||
.small-4.medium-4.large-6.columns.variant-name
|
||||
.small-4.medium-4.large-5.columns.variant-name
|
||||
.inline{"ng-if" => "::variant.display_name"} {{ ::variant.display_name }}
|
||||
.variant-unit {{ ::variant.unit_to_display }}
|
||||
.small-3.medium-3.large-2.columns.variant-price
|
||||
@@ -8,7 +8,7 @@
|
||||
"price-breakdown-placement" => "bottom",
|
||||
"price-breakdown-animation" => true}
|
||||
{{ variant.price_with_fees | localizeCurrency }}
|
||||
.medium-2.large-1.columns.total-price
|
||||
.medium-2.large-2.columns.total-price
|
||||
%span{"ng-class" => "{filled: variant.line_item.total_price}"}
|
||||
{{ variant.line_item.total_price | localizeCurrency }}
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
*
|
||||
|
||||
*= require normalize
|
||||
*= require skeleton
|
||||
*= require responsive-tables
|
||||
*= require jquery.powertip
|
||||
*= require jquery.ui.datepicker
|
||||
|
||||
@@ -65,12 +65,17 @@ nav.menu {
|
||||
#admin-menu {
|
||||
background-color: $color-3;
|
||||
|
||||
ul {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
li {
|
||||
min-width: 90px;
|
||||
flex-grow: 1;
|
||||
|
||||
a {
|
||||
display: block;
|
||||
padding: 25px 20px;
|
||||
padding: 25px 5px;
|
||||
color: $color-1 !important;
|
||||
text-transform: uppercase;
|
||||
position: relative;
|
||||
@@ -160,3 +165,11 @@ nav.menu {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#header figure {
|
||||
margin: 0.25em 0;
|
||||
}
|
||||
|
||||
#login-nav {
|
||||
line-height: 1.75em;
|
||||
}
|
||||
|
||||
@@ -66,7 +66,6 @@ div.dashboard_item {
|
||||
|
||||
a {
|
||||
border-radius: 0px 4px 0px 0px;
|
||||
margin-left: 8px;
|
||||
height: 100%;
|
||||
padding: 15px 2px 0px 2px;
|
||||
}
|
||||
|
||||
134
app/assets/stylesheets/admin/grid.scss
Normal file
134
app/assets/stylesheets/admin/grid.scss
Normal file
@@ -0,0 +1,134 @@
|
||||
// Grid Calculations
|
||||
// Adjust $col-gutter (space between columns, as percentage) to adjust everything else automatically
|
||||
|
||||
$col-gutter: 2;
|
||||
$total-gutter: $col-gutter * 15;
|
||||
$total-colspace: 100 - $total-gutter;
|
||||
$gutter-width: $col-gutter / 100;
|
||||
$col-width: ($total-colspace / 16) / 100;
|
||||
|
||||
$col-1: $col-width;
|
||||
$col-2: ($col-width * 2) + $gutter-width;
|
||||
$col-3: ($col-width * 3) + ($gutter-width * 2);
|
||||
$col-4: ($col-width * 4) + ($gutter-width * 3);
|
||||
$col-5: ($col-width * 5) + ($gutter-width * 4);
|
||||
$col-6: ($col-width * 6) + ($gutter-width * 5);
|
||||
$col-7: ($col-width * 7) + ($gutter-width * 6);
|
||||
$col-8: ($col-width * 8) + ($gutter-width * 7);
|
||||
$col-9: ($col-width * 9) + ($gutter-width * 8);
|
||||
$col-10: ($col-width * 10) + ($gutter-width * 9);
|
||||
$col-11: ($col-width * 11) + ($gutter-width * 10);
|
||||
$col-12: ($col-width * 12) + ($gutter-width * 11);
|
||||
$col-13: ($col-width * 13) + ($gutter-width * 12);
|
||||
$col-14: ($col-width * 14) + ($gutter-width * 13);
|
||||
$col-15: ($col-width * 15) + ($gutter-width * 14);
|
||||
$col-16: 100;
|
||||
|
||||
// Grid Classes
|
||||
|
||||
.container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
padding: 0 1.5%;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
max-width: 1400px;
|
||||
|
||||
&.no-gutter {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.row {
|
||||
width: 100%;
|
||||
margin-bottom: 1.5em;
|
||||
}
|
||||
}
|
||||
|
||||
.container::after,
|
||||
.row::after,
|
||||
.clearfix::after,
|
||||
.clear::after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.column,
|
||||
.columns {
|
||||
margin-left: percentage($gutter-width);
|
||||
float: left;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.column.one,
|
||||
.columns.one { width: percentage($col-1); }
|
||||
|
||||
.columns.two { width: percentage($col-2); }
|
||||
|
||||
.columns.three { width: percentage($col-3); }
|
||||
|
||||
.columns.four { width: percentage($col-4); }
|
||||
|
||||
.columns.five { width: percentage($col-5); }
|
||||
|
||||
.columns.six { width: percentage($col-6); }
|
||||
|
||||
.columns.seven { width: percentage($col-7); }
|
||||
|
||||
.columns.eight { width: percentage($col-8); }
|
||||
|
||||
.columns.nine { width: percentage($col-9); }
|
||||
|
||||
.columns.ten { width: percentage($col-10); }
|
||||
|
||||
.columns.eleven { width: percentage($col-11); }
|
||||
|
||||
.columns.twelve { width: percentage($col-12); }
|
||||
|
||||
.columns.thirteen { width: percentage($col-13); }
|
||||
|
||||
.columns.fourteen { width: percentage($col-14);}
|
||||
|
||||
.columns.fifteen { width: percentage($col-15); }
|
||||
|
||||
.columns.sixteen { width: 100%; }
|
||||
|
||||
.column.offset-by-one,
|
||||
.columns.offset-by-one { margin-left: $col-2; }
|
||||
|
||||
.columns.offset-by-two { margin-left: $col-3; }
|
||||
|
||||
.columns.offset-by-three { margin-left: $col-4; }
|
||||
|
||||
.columns.offset-by-four { margin-left: $col-5; }
|
||||
|
||||
.columns.offset-by-five { margin-left: $col-6; }
|
||||
|
||||
.columns.offset-by-six { margin-left: $col-7; }
|
||||
|
||||
.columns.offset-by-seven { margin-left: $col-8; }
|
||||
|
||||
.columns.offset-by-eight { margin-left: $col-9; }
|
||||
|
||||
.columns.offset-by-nine { margin-left: $col-10; }
|
||||
|
||||
.columns.offset-by-ten { margin-left: $col-11; }
|
||||
|
||||
.columns.offset-by-eleven { margin-left: $col-12; }
|
||||
|
||||
.columns.offset-by-twelve { margin-left: $col-13; }
|
||||
|
||||
.columns.offset-by-thirteen { margin-left: $col-14; }
|
||||
|
||||
.columns.offset-by-fourteen { margin-left: $col-15; }
|
||||
|
||||
.columns.offset-by-fifteen { margin-left: 100%; }
|
||||
|
||||
.column.alpha,
|
||||
.columns.alpha,
|
||||
.columns.sixteen,
|
||||
.column:first-child,
|
||||
.columns:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
@@ -185,6 +185,7 @@ fieldset {
|
||||
text-transform: uppercase;
|
||||
text-align: center;
|
||||
padding: 8px 15px;
|
||||
margin: 0 auto;
|
||||
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
}
|
||||
|
||||
.icon-email:before { @extend .icon-envelope:before }
|
||||
.icon-resend_authorization_email:before { @extend .icon-envelope:before }
|
||||
.icon-resume:before { @extend .icon-refresh:before }
|
||||
|
||||
.icon-cancel:before,
|
||||
|
||||
@@ -6,15 +6,25 @@
|
||||
.darkswarm {
|
||||
// #search
|
||||
@include placeholder(rgba(0, 0, 0, 0.4), #777);
|
||||
|
||||
.row .columns.variant-quantity-column {
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.reveal-modal.product-bulk-modal {
|
||||
width: 26em;
|
||||
width: 27em;
|
||||
}
|
||||
|
||||
// Components to add variants to cart and change quantities
|
||||
//
|
||||
// They are not nested so that they can be used in modals.
|
||||
|
||||
.variant-quantity-inputs {
|
||||
height: 2.5rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
button.add-variant, button.variant-quantity {
|
||||
height: 2.5rem;
|
||||
border-radius: 0;
|
||||
@@ -48,7 +58,7 @@ button.add-variant, button.variant-quantity {
|
||||
}
|
||||
|
||||
button.add-variant {
|
||||
min-width: 6rem;
|
||||
min-width: 7rem;
|
||||
padding: 0 1em;
|
||||
|
||||
&[disabled] {
|
||||
@@ -59,7 +69,7 @@ button.add-variant {
|
||||
}
|
||||
|
||||
button.variant-quantity {
|
||||
width: 3rem;
|
||||
width: 2.25rem;
|
||||
|
||||
&:nth-of-type(1):not(.bulk-buy):not(.bulk-buy-add) {
|
||||
border-right: .1em solid $orange-400;
|
||||
@@ -71,7 +81,7 @@ button.variant-quantity {
|
||||
font-size: 0.875em;
|
||||
margin-top: 0.25em;
|
||||
text-align: center;
|
||||
width: 6rem;
|
||||
width: 7rem;
|
||||
visibility: hidden;
|
||||
|
||||
&.visible {
|
||||
@@ -83,20 +93,28 @@ button.bulk-buy.variant-quantity {
|
||||
background-color: transparent;
|
||||
border: .1em solid $grey-200;
|
||||
color: inherit;
|
||||
width: 3.5rem;
|
||||
}
|
||||
|
||||
button.bulk-buy-add.variant-quantity {
|
||||
width: 2.5rem;
|
||||
}
|
||||
|
||||
span.bulk-buy.variant-quantity {
|
||||
[type="number"].variant-quantity {
|
||||
border: .1em solid $grey-200;
|
||||
height: 2.5rem;
|
||||
display: inline-block;
|
||||
min-width: 3em;
|
||||
padding: .5em;
|
||||
width: 2.5rem;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
vertical-align: top;
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: textfield;
|
||||
|
||||
&.bulk-buy {
|
||||
width: 5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.variant-bulk-buy-price-summary {
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
// See https://github.com/zurb/foundation/issues/3855#issuecomment-30372252
|
||||
|
||||
@import "variables";
|
||||
@import "components/global";
|
||||
@import "components/buttons";
|
||||
@import "components/panels";
|
||||
@import "foundation/components/global";
|
||||
@import "foundation/components/buttons";
|
||||
@import "foundation/components/panels";
|
||||
|
||||
#sidebar {
|
||||
margin-top: 1.875em;
|
||||
|
||||
@@ -29,7 +29,8 @@ module Admin
|
||||
collection_hash = Hash[permitted_params[:column_preferences].
|
||||
each_with_index.map { |cp, i| [i, cp] }]
|
||||
collection_hash.select!{ |_i, cp| cp[:action_name] == permitted_params[:action_name] }
|
||||
@cp_set = ColumnPreferenceSet.new @column_preferences, collection_attributes: collection_hash
|
||||
@cp_set = Sets::ColumnPreferenceSet.new(@column_preferences,
|
||||
collection_attributes: collection_hash)
|
||||
end
|
||||
|
||||
def collection
|
||||
|
||||
@@ -27,7 +27,7 @@ module Admin
|
||||
end
|
||||
|
||||
def bulk_update
|
||||
@enterprise_fee_set = EnterpriseFeeSet.new(enterprise_fee_bulk_params)
|
||||
@enterprise_fee_set = Sets::EnterpriseFeeSet.new(enterprise_fee_bulk_params)
|
||||
|
||||
if @enterprise_fee_set.save
|
||||
redirect_to redirect_path, notice: I18n.t(:enterprise_fees_update_notice)
|
||||
@@ -40,7 +40,7 @@ module Admin
|
||||
private
|
||||
|
||||
def load_enterprise_fee_set
|
||||
@enterprise_fee_set = EnterpriseFeeSet.new collection: collection
|
||||
@enterprise_fee_set = Sets::EnterpriseFeeSet.new collection: collection
|
||||
end
|
||||
|
||||
def load_data
|
||||
@@ -80,7 +80,7 @@ module Admin
|
||||
end
|
||||
|
||||
def enterprise_fee_bulk_params
|
||||
params.require(:enterprise_fee_set).permit(
|
||||
params.require(:sets_enterprise_fee_set).permit(
|
||||
collection_attributes: [
|
||||
:id, :enterprise_id, :fee_type, :name, :tax_category_id,
|
||||
:inherits_tax_category, :calculator_type,
|
||||
|
||||
@@ -81,7 +81,7 @@ module Admin
|
||||
end
|
||||
|
||||
def bulk_update
|
||||
@enterprise_set = EnterpriseSet.new(collection, bulk_params)
|
||||
@enterprise_set = Sets::EnterpriseSet.new(collection, bulk_params)
|
||||
if @enterprise_set.save
|
||||
flash[:success] = I18n.t(:enterprise_bulk_update_success_notice)
|
||||
|
||||
@@ -129,7 +129,7 @@ module Admin
|
||||
private
|
||||
|
||||
def load_enterprise_set
|
||||
@enterprise_set = EnterpriseSet.new(collection) if spree_current_user.admin?
|
||||
@enterprise_set = Sets::EnterpriseSet.new(collection) if spree_current_user.admin?
|
||||
end
|
||||
|
||||
def load_countries
|
||||
@@ -235,7 +235,7 @@ module Admin
|
||||
|
||||
def check_can_change_bulk_sells
|
||||
unless spree_current_user.admin?
|
||||
params[:enterprise_set][:collection_attributes].each do |_i, enterprise_params|
|
||||
params[:sets_enterprise_set][:collection_attributes].each do |_i, enterprise_params|
|
||||
unless spree_current_user == Enterprise.find_by(id: enterprise_params[:id]).owner
|
||||
enterprise_params.delete :sells
|
||||
end
|
||||
@@ -269,7 +269,7 @@ module Admin
|
||||
|
||||
def check_can_change_bulk_owner
|
||||
unless spree_current_user.admin?
|
||||
params[:enterprise_set][:collection_attributes].each do |_i, enterprise_params|
|
||||
params[:sets_enterprise_set][:collection_attributes].each do |_i, enterprise_params|
|
||||
enterprise_params.delete :owner_id
|
||||
end
|
||||
end
|
||||
@@ -321,7 +321,7 @@ module Admin
|
||||
end
|
||||
|
||||
def bulk_params
|
||||
params.require(:enterprise_set).permit(
|
||||
params.require(:sets_enterprise_set).permit(
|
||||
collection_attributes: PermittedAttributes::Enterprise.attributes
|
||||
)
|
||||
end
|
||||
|
||||
@@ -223,7 +223,7 @@ module Admin
|
||||
end
|
||||
|
||||
def order_cycle_set
|
||||
@order_cycle_set ||= OrderCycleSet.new(@order_cycles, order_cycle_bulk_params)
|
||||
@order_cycle_set ||= Sets::OrderCycleSet.new(@order_cycles, order_cycle_bulk_params)
|
||||
end
|
||||
|
||||
def require_order_cycle_set_params
|
||||
|
||||
@@ -60,14 +60,17 @@ module Admin
|
||||
for_hubs(editable_enterprises.collect(&:id))
|
||||
|
||||
options = [{ id: '0', name: 'All' }]
|
||||
import_dates.collect(&:import_date).map { |i| options.push(id: i.to_date, name: i.to_date.to_formatted_s(:long)) }
|
||||
import_dates.collect(&:import_date).map { |i|
|
||||
options.push(id: i.to_date, name: i.to_date.to_formatted_s(:long))
|
||||
}
|
||||
|
||||
options
|
||||
end
|
||||
|
||||
def load_collection
|
||||
collection_hash = Hash[variant_overrides_params.each_with_index.map { |vo, i| [i, vo] }]
|
||||
@vo_set = VariantOverrideSet.new @variant_overrides, collection_attributes: collection_hash
|
||||
@vo_set = Sets::VariantOverrideSet.new(@variant_overrides,
|
||||
collection_attributes: collection_hash)
|
||||
end
|
||||
|
||||
def collection
|
||||
@@ -82,8 +85,8 @@ module Admin
|
||||
[:index, :bulk_update, :bulk_reset]
|
||||
end
|
||||
|
||||
# This has been pulled from ModelSet as it is useful for compiling a list of errors on any generic collection (not necessarily a ModelSet)
|
||||
# Could be pulled down into a lower level controller if it is useful in other high level controllers
|
||||
# This method is also present in ModelSet
|
||||
# This is useful for compiling a list of errors on any generic collection
|
||||
def collection_errors
|
||||
errors = ActiveModel::Errors.new self
|
||||
full_messages = @collection.map { |element| element.errors.full_messages }.flatten
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "application_responder"
|
||||
require 'open_food_network/referer_parser'
|
||||
require_dependency 'spree/authentication_helpers'
|
||||
require "application_responder"
|
||||
require 'cancan'
|
||||
require 'spree/core/controller_helpers/auth'
|
||||
require 'spree/core/controller_helpers/respond_with'
|
||||
require 'spree/core/controller_helpers/ssl'
|
||||
require 'spree/core/controller_helpers/common'
|
||||
require 'open_food_network/referer_parser'
|
||||
|
||||
class ApplicationController < ActionController::Base
|
||||
self.responder = ApplicationResponder
|
||||
@@ -10,6 +15,11 @@ class ApplicationController < ActionController::Base
|
||||
|
||||
protect_from_forgery
|
||||
|
||||
include Spree::Core::ControllerHelpers::Auth
|
||||
include Spree::Core::ControllerHelpers::RespondWith
|
||||
include Spree::Core::ControllerHelpers::SSL
|
||||
include Spree::Core::ControllerHelpers::Common
|
||||
|
||||
prepend_before_action :restrict_iframes
|
||||
before_action :set_cache_headers # prevent cart emptying via cache when using back button #1213
|
||||
|
||||
@@ -22,6 +32,8 @@ class ApplicationController < ActionController::Base
|
||||
raise ActiveModel::ForbiddenAttributesError, params.to_s
|
||||
end
|
||||
|
||||
respond_to :html
|
||||
|
||||
def redirect_to(options = {}, response_status = {})
|
||||
::Rails.logger.error("Redirected by #{begin
|
||||
caller(1).first
|
||||
@@ -123,7 +135,6 @@ class ApplicationController < ActionController::Base
|
||||
|
||||
def check_order_cycle_expiry
|
||||
if current_order_cycle.andand.closed?
|
||||
session[:expired_order_cycle_id] = current_order_cycle.id
|
||||
current_order.empty!
|
||||
current_order.set_order_cycle! nil
|
||||
flash[:info] = I18n.t('order_cycle_closed')
|
||||
@@ -150,3 +161,5 @@ class ApplicationController < ActionController::Base
|
||||
response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 GMT"
|
||||
end
|
||||
end
|
||||
|
||||
require 'spree/i18n/initializer'
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
require 'spree/core/controller_helpers/auth'
|
||||
require 'spree/core/controller_helpers/common'
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spree/core/controller_helpers/order'
|
||||
require 'spree/core/controller_helpers/respond_with'
|
||||
require 'spree/core/controller_helpers/ssl'
|
||||
require 'open_food_network/tag_rule_applicator'
|
||||
|
||||
class BaseController < ApplicationController
|
||||
include Spree::Core::ControllerHelpers::Auth
|
||||
include Spree::Core::ControllerHelpers::Common
|
||||
layout 'darkswarm'
|
||||
|
||||
include Spree::Core::ControllerHelpers::Order
|
||||
include Spree::Core::ControllerHelpers::RespondWith
|
||||
include Spree::Core::ControllerHelpers::SSL
|
||||
|
||||
include I18nHelper
|
||||
include EnterprisesHelper
|
||||
include OrderCyclesHelper
|
||||
|
||||
helper 'spree/base'
|
||||
|
||||
@@ -11,7 +11,7 @@ class CartController < BaseController
|
||||
Spree::Adjustment.without_callbacks do
|
||||
cart_service = CartService.new(order)
|
||||
|
||||
cart_service.populate(params.slice(:products, :variants, :quantity), true)
|
||||
cart_service.populate(params.slice(:variants, :quantity), true)
|
||||
if cart_service.valid?
|
||||
order.update_distribution_charge!
|
||||
order.cap_quantity_at_stock!
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
require 'open_food_network/address_finder'
|
||||
|
||||
class CheckoutController < Spree::StoreController
|
||||
class CheckoutController < ::BaseController
|
||||
layout 'darkswarm'
|
||||
|
||||
include OrderStockCheck
|
||||
@@ -142,7 +142,7 @@ class CheckoutController < Spree::StoreController
|
||||
def handle_redirect_from_stripe
|
||||
if OrderWorkflow.new(@order).next && order_complete?
|
||||
checkout_succeeded
|
||||
redirect_to(spree.order_path(@order)) && return
|
||||
redirect_to(order_path(@order)) && return
|
||||
else
|
||||
checkout_failed
|
||||
end
|
||||
@@ -202,10 +202,10 @@ class CheckoutController < Spree::StoreController
|
||||
def update_succeeded_response
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
respond_with(@order, location: spree.order_path(@order))
|
||||
respond_with(@order, location: order_path(@order))
|
||||
end
|
||||
format.json do
|
||||
render json: { path: spree.order_path(@order) }, status: :ok
|
||||
render json: { path: order_path(@order) }, status: :ok
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
29
app/controllers/payments_controller.rb
Normal file
29
app/controllers/payments_controller.rb
Normal file
@@ -0,0 +1,29 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class PaymentsController < BaseController
|
||||
ssl_required :redirect_to_authorize
|
||||
|
||||
respond_to :html
|
||||
|
||||
prepend_before_action :require_logged_in, only: :redirect_to_authorize
|
||||
|
||||
def redirect_to_authorize
|
||||
@payment = Spree::Payment.find(params[:id])
|
||||
authorize! :show, @payment.order
|
||||
|
||||
if url = @payment.cvv_response_message
|
||||
redirect_to url
|
||||
else
|
||||
redirect_to order_url(@payment.order)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def require_logged_in
|
||||
return if session[:access_token] || params[:token] || spree_current_user
|
||||
|
||||
flash[:error] = I18n.t("spree.orders.edit.login_to_view_order")
|
||||
redirect_to main_app.root_path(anchor: "login?after_login=#{request.env['PATH_INFO']}")
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,29 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class PaymentsController < BaseController
|
||||
ssl_required :redirect_to_authorize
|
||||
|
||||
respond_to :html
|
||||
|
||||
prepend_before_action :require_logged_in, only: :redirect_to_authorize
|
||||
|
||||
def redirect_to_authorize
|
||||
@payment = Spree::Payment.find(params[:id])
|
||||
authorize! :show, @payment.order
|
||||
|
||||
if url = @payment.cvv_response_message
|
||||
redirect_to url
|
||||
else
|
||||
redirect_to order_url(@payment.order)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def require_logged_in
|
||||
return if session[:access_token] || params[:token] || spree_current_user
|
||||
|
||||
flash[:error] = I18n.t("spree.orders.edit.login_to_view_order")
|
||||
redirect_to main_app.root_path(anchor: "login?after_login=#{request.env['PATH_INFO']}")
|
||||
end
|
||||
end
|
||||
@@ -1,6 +1,6 @@
|
||||
module Spree
|
||||
module Admin
|
||||
class BaseController < Spree::BaseController
|
||||
class BaseController < ApplicationController
|
||||
ssl_required
|
||||
|
||||
helper 'spree/admin/navigation'
|
||||
|
||||
@@ -56,7 +56,7 @@ module Spree
|
||||
|
||||
# Because we have a transition method also called void, we do this to avoid conflicts.
|
||||
event = "void_transaction" if event == "void"
|
||||
if @payment.public_send("#{event}!")
|
||||
if allowed_events.include?(event) && @payment.public_send("#{event}!")
|
||||
flash[:success] = t(:payment_updated)
|
||||
else
|
||||
flash[:error] = t(:cannot_perform_operation)
|
||||
@@ -116,7 +116,7 @@ module Spree
|
||||
# Only show payments for the order's distributor
|
||||
@payment_methods = PaymentMethod.
|
||||
available(:back_end).
|
||||
select{ |pm| pm.has_distributor? @order.distributor }
|
||||
for_distributor(@order.distributor)
|
||||
|
||||
@payment_method = if @payment&.payment_method
|
||||
@payment.payment_method
|
||||
@@ -153,10 +153,18 @@ module Spree
|
||||
def authorize_stripe_sca_payment
|
||||
return unless @payment.payment_method.class == Spree::Gateway::StripeSCA
|
||||
|
||||
@payment.authorize!
|
||||
return if @payment.pending? && @payment.cvv_response_message.nil?
|
||||
@payment.authorize!(main_app.order_path(@payment.order, only_path: false))
|
||||
|
||||
raise Spree::Core::GatewayError, I18n.t('authorization_failure')
|
||||
raise Spree::Core::GatewayError, I18n.t('authorization_failure') unless @payment.pending?
|
||||
|
||||
return unless @payment.cvv_response_message.present?
|
||||
|
||||
PaymentMailer.authorize_payment(@payment).deliver_later
|
||||
raise Spree::Core::GatewayError, I18n.t('action_required')
|
||||
end
|
||||
|
||||
def allowed_events
|
||||
%w{capture void_transaction credit refund resend_authorization_email}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -163,7 +163,7 @@ module Spree
|
||||
|
||||
def product_set_from_params(_params)
|
||||
collection_hash = Hash[products_params.each_with_index.map { |p, i| [i, p] }]
|
||||
Spree::ProductSet.new(collection_attributes: collection_hash)
|
||||
Sets::ProductSet.new(collection_attributes: collection_hash)
|
||||
end
|
||||
|
||||
def products_params
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'cancan'
|
||||
require 'spree/core/controller_helpers/auth'
|
||||
require 'spree/core/controller_helpers/respond_with'
|
||||
require 'spree/core/controller_helpers/ssl'
|
||||
require 'spree/core/controller_helpers/common'
|
||||
|
||||
module Spree
|
||||
class BaseController < ApplicationController
|
||||
include Spree::Core::ControllerHelpers::Auth
|
||||
include Spree::Core::ControllerHelpers::RespondWith
|
||||
include Spree::Core::ControllerHelpers::SSL
|
||||
include Spree::Core::ControllerHelpers::Common
|
||||
|
||||
respond_to :html
|
||||
end
|
||||
end
|
||||
|
||||
require 'spree/i18n/initializer'
|
||||
@@ -7,7 +7,7 @@
|
||||
# to CheckoutController directly in the routes
|
||||
# with a slash like "to: '/checkout#edit'", but it does not work in this case.
|
||||
module Spree
|
||||
class CheckoutController < Spree::StoreController
|
||||
class CheckoutController < ::BaseController
|
||||
def edit
|
||||
flash.keep
|
||||
redirect_to main_app.checkout_path
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
module Spree
|
||||
class OrdersController < Spree::StoreController
|
||||
class OrdersController < ::BaseController
|
||||
include OrderCyclesHelper
|
||||
include Rails.application.routes.url_helpers
|
||||
|
||||
@@ -85,7 +85,7 @@ module Spree
|
||||
@order.next_transition.run_callbacks if @order.cart?
|
||||
redirect_to checkout_state_path(@order.checkout_steps.first)
|
||||
elsif @order.complete?
|
||||
redirect_to spree.order_path(@order)
|
||||
redirect_to order_path(@order)
|
||||
else
|
||||
redirect_to main_app.cart_path
|
||||
end
|
||||
@@ -132,27 +132,16 @@ module Spree
|
||||
end
|
||||
end
|
||||
|
||||
def clear
|
||||
@order = current_order(true)
|
||||
@order.empty!
|
||||
@order.set_order_cycle! nil
|
||||
redirect_to main_app.enterprise_path(@order.distributor.id)
|
||||
end
|
||||
|
||||
def order_cycle_expired
|
||||
@order_cycle = OrderCycle.find session[:expired_order_cycle_id]
|
||||
end
|
||||
|
||||
def cancel
|
||||
@order = Spree::Order.find_by!(number: params[:id])
|
||||
authorize! :cancel, @order
|
||||
|
||||
if @order.cancel
|
||||
if CustomerOrderCancellation.new(@order).call
|
||||
flash[:success] = I18n.t(:orders_your_order_has_been_cancelled)
|
||||
else
|
||||
flash[:error] = I18n.t(:orders_could_not_cancel)
|
||||
end
|
||||
redirect_to request.referer || spree.order_path(@order)
|
||||
redirect_to request.referer || order_path(@order)
|
||||
end
|
||||
|
||||
private
|
||||
@@ -216,7 +205,7 @@ module Spree
|
||||
|
||||
if items.empty?
|
||||
flash[:error] = I18n.t(:orders_cannot_remove_the_final_item)
|
||||
redirect_to spree.order_path(order_to_update)
|
||||
redirect_to order_path(order_to_update)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Spree
|
||||
class PaypalController < StoreController
|
||||
class PaypalController < ::BaseController
|
||||
ssl_allowed
|
||||
|
||||
include OrderStockCheck
|
||||
@@ -234,7 +234,7 @@ module Spree
|
||||
end
|
||||
|
||||
def completion_route(order)
|
||||
spree.order_path(order, token: order.token)
|
||||
main_app.order_path(order, token: order.token)
|
||||
end
|
||||
|
||||
def address_required?
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spree/core/controller_helpers/order'
|
||||
|
||||
module Spree
|
||||
class StoreController < Spree::BaseController
|
||||
layout 'darkswarm'
|
||||
|
||||
include Spree::Core::ControllerHelpers::Order
|
||||
|
||||
include I18nHelper
|
||||
before_action :set_locale
|
||||
end
|
||||
end
|
||||
@@ -1,5 +1,5 @@
|
||||
module Spree
|
||||
class UsersController < Spree::StoreController
|
||||
class UsersController < ::BaseController
|
||||
layout 'darkswarm'
|
||||
ssl_required
|
||||
skip_before_action :set_current_order, only: :show
|
||||
@@ -12,9 +12,13 @@ module Spree
|
||||
before_action :set_locale
|
||||
before_action :enable_embedded_shopfront
|
||||
|
||||
# Ignores invoice orders, only order where state: 'complete'
|
||||
def show
|
||||
@orders = @user.orders.where(state: 'complete').order('completed_at desc')
|
||||
@orders = orders_collection
|
||||
|
||||
customers = spree_current_user.customers
|
||||
@shops = Enterprise
|
||||
.where(id: @orders.pluck(:distributor_id).uniq | customers.pluck(:enterprise_id))
|
||||
|
||||
@unconfirmed_email = spree_current_user.unconfirmed_email
|
||||
end
|
||||
|
||||
@@ -54,6 +58,14 @@ module Spree
|
||||
|
||||
private
|
||||
|
||||
def orders_collection
|
||||
if OpenFoodNetwork::FeatureToggle.enabled?(:customer_balance, spree_current_user)
|
||||
CompleteOrdersWithBalance.new(@user).query
|
||||
else
|
||||
@user.orders.where(state: 'complete').order('completed_at desc')
|
||||
end
|
||||
end
|
||||
|
||||
def load_object
|
||||
@user ||= spree_current_user
|
||||
if @user
|
||||
|
||||
@@ -19,7 +19,7 @@ module CheckoutHelper
|
||||
adjustments.reject! { |a| a.originator_type == 'EnterpriseFee' && a.source_type != 'Spree::LineItem' }
|
||||
unless exclude.include? :admin_and_handling
|
||||
adjustments << Spree::Adjustment.new(
|
||||
label: I18n.t(:orders_form_admin), amount: enterprise_fee_adjustments.map(&:amount).sum
|
||||
label: I18n.t(:orders_form_admin), amount: enterprise_fee_adjustments.sum(&:amount)
|
||||
)
|
||||
end
|
||||
|
||||
@@ -28,7 +28,7 @@ module CheckoutHelper
|
||||
|
||||
def display_checkout_admin_and_handling_adjustments_total_for(order)
|
||||
adjustments = order.adjustments.eligible.where('originator_type = ? AND source_type != ? ', 'EnterpriseFee', 'Spree::LineItem')
|
||||
Spree::Money.new adjustments.map(&:amount).sum, currency: order.currency
|
||||
Spree::Money.new adjustments.sum(:amount), currency: order.currency
|
||||
end
|
||||
|
||||
def checkout_line_item_adjustments(order)
|
||||
@@ -36,7 +36,7 @@ module CheckoutHelper
|
||||
end
|
||||
|
||||
def checkout_subtotal(order)
|
||||
order.item_total + checkout_line_item_adjustments(order).map(&:amount).sum
|
||||
order.item_total + checkout_line_item_adjustments(order).sum(:amount)
|
||||
end
|
||||
|
||||
def display_checkout_subtotal(order)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
module EnterpriseFeesHelper
|
||||
def angular_name(method)
|
||||
"enterprise_fee_set[collection_attributes][{{ $index }}][#{method}]"
|
||||
"sets_enterprise_fee_set[collection_attributes][{{ $index }}][#{method}]"
|
||||
end
|
||||
|
||||
def angular_id(method)
|
||||
"enterprise_fee_set_collection_attributes_{{ $index }}_#{method}"
|
||||
"sets_enterprise_fee_set_collection_attributes_{{ $index }}_#{method}"
|
||||
end
|
||||
|
||||
def enterprise_fee_type_options
|
||||
|
||||
@@ -28,7 +28,7 @@ module Spree
|
||||
end
|
||||
|
||||
def changeable_orders_link_path
|
||||
changeable_orders.one? ? spree.order_path(changeable_orders.first) : spree.account_path
|
||||
changeable_orders.one? ? order_path(changeable_orders.first) : spree.account_path
|
||||
end
|
||||
|
||||
def shop_changeable_orders_alert_html
|
||||
|
||||
14
app/mailers/payment_mailer.rb
Normal file
14
app/mailers/payment_mailer.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class PaymentMailer < Spree::BaseMailer
|
||||
include I18nHelper
|
||||
|
||||
def authorize_payment(payment)
|
||||
@payment = payment
|
||||
subject = I18n.t('spree.payment_mailer.authorize_payment.subject',
|
||||
distributor: @payment.order.distributor.name)
|
||||
mail(to: payment.order.user.email,
|
||||
from: from_address,
|
||||
subject: subject)
|
||||
end
|
||||
end
|
||||
@@ -17,6 +17,16 @@ module Spree
|
||||
end
|
||||
end
|
||||
|
||||
def cancel_email_for_shop(order)
|
||||
@order = order
|
||||
I18n.with_locale valid_locale(@order.distributor.owner) do
|
||||
subject = I18n.t('spree.order_mailer.cancel_email_for_shop.subject')
|
||||
mail(to: @order.distributor.contact.email,
|
||||
from: from_address,
|
||||
subject: subject)
|
||||
end
|
||||
end
|
||||
|
||||
def confirm_email_for_customer(order_or_order_id, resend = false)
|
||||
@order = find_order(order_or_order_id)
|
||||
I18n.with_locale valid_locale(@order.user) do
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
class ColumnPreferenceSet < ModelSet
|
||||
def initialize(collection, attributes = {})
|
||||
super(ColumnPreference, collection, attributes, nil, nil )
|
||||
end
|
||||
end
|
||||
@@ -1,6 +1,8 @@
|
||||
class EnterpriseFee < ActiveRecord::Base
|
||||
include Spree::Core::CalculatedAdjustments
|
||||
|
||||
acts_as_paranoid
|
||||
|
||||
belongs_to :enterprise
|
||||
belongs_to :tax_category, class_name: 'Spree::TaxCategory', foreign_key: 'tax_category_id'
|
||||
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
class EnterpriseFeeSet < ModelSet
|
||||
def initialize(attributes = {})
|
||||
super(EnterpriseFee, EnterpriseFee.all,
|
||||
attributes,
|
||||
proc { |attrs| attrs[:name].blank? })
|
||||
end
|
||||
end
|
||||
@@ -1,5 +0,0 @@
|
||||
class EnterpriseSet < ModelSet
|
||||
def initialize(collection, attributes = {})
|
||||
super(Enterprise, collection, attributes)
|
||||
end
|
||||
end
|
||||
@@ -1,65 +0,0 @@
|
||||
# Tableless model to handle updating multiple models at once from a single form
|
||||
class ModelSet
|
||||
include ActiveModel::Conversion
|
||||
extend ActiveModel::Naming
|
||||
|
||||
attr_accessor :collection
|
||||
|
||||
def initialize(klass, collection, attributes = {}, reject_if = nil, delete_if = nil)
|
||||
@klass, @collection, @reject_if, @delete_if = klass, collection, reject_if, delete_if
|
||||
|
||||
# Set here first, to ensure that we apply collection_attributes to the right collection
|
||||
@collection = attributes[:collection] if attributes[:collection]
|
||||
|
||||
attributes.each do |name, value|
|
||||
public_send("#{name}=", value)
|
||||
end
|
||||
end
|
||||
|
||||
def collection_attributes=(collection_attributes)
|
||||
collection_attributes.each do |_k, attributes|
|
||||
# attributes == {:id => 123, :next_collection_at => '...'}
|
||||
found_element = @collection.detect do |element|
|
||||
element.id.to_s == attributes[:id].to_s && !element.id.nil?
|
||||
end
|
||||
|
||||
if found_element.nil?
|
||||
@collection << @klass.new(attributes) unless @reject_if.andand.call(attributes)
|
||||
else
|
||||
found_element.assign_attributes(attributes.except(:id))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def errors
|
||||
errors = ActiveModel::Errors.new self
|
||||
full_messages = @collection
|
||||
.map { |model| model.errors.full_messages }
|
||||
.flatten
|
||||
|
||||
full_messages.each { |message| errors.add(:base, message) }
|
||||
errors
|
||||
end
|
||||
|
||||
def save
|
||||
collection_to_delete.each(&:destroy)
|
||||
collection_to_keep.all?(&:save)
|
||||
end
|
||||
|
||||
def collection_to_delete
|
||||
# Remove all elements to be deleted from collection and return them
|
||||
# Allows us to render @model_set.collection without deleted elements
|
||||
deleted = []
|
||||
@collection = collection.to_a
|
||||
collection.delete_if { |e| deleted << e if @delete_if.andand.call(e.attributes) }
|
||||
deleted
|
||||
end
|
||||
|
||||
def collection_to_keep
|
||||
collection.reject { |e| @delete_if.andand.call(e.attributes) }
|
||||
end
|
||||
|
||||
def persisted?
|
||||
false
|
||||
end
|
||||
end
|
||||
@@ -1,5 +0,0 @@
|
||||
class OrderCycleSet < ModelSet
|
||||
def initialize(collection, attributes = {})
|
||||
super(OrderCycle, collection, attributes)
|
||||
end
|
||||
end
|
||||
@@ -39,6 +39,8 @@ module Spree
|
||||
belongs_to :adjustable, polymorphic: true
|
||||
belongs_to :source, polymorphic: true
|
||||
belongs_to :originator, polymorphic: true
|
||||
belongs_to :order, class_name: "Spree::Order"
|
||||
|
||||
belongs_to :tax_rate, -> { where spree_adjustments: { originator_type: 'Spree::TaxRate' } },
|
||||
foreign_key: 'originator_id'
|
||||
|
||||
@@ -160,6 +162,13 @@ module Spree
|
||||
result
|
||||
end
|
||||
|
||||
# Allow accessing soft-deleted originator objects
|
||||
def originator
|
||||
return if originator_type.blank?
|
||||
|
||||
originator_type.constantize.unscoped { super }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def update_adjustable
|
||||
|
||||
@@ -92,13 +92,11 @@ module Spree
|
||||
preference :s3_host_alias, :string
|
||||
|
||||
# Default mail headers settings
|
||||
preference :enable_mail_delivery, :boolean, default: false
|
||||
preference :mails_from, :string, default: 'ofn@example.com'
|
||||
preference :mail_bcc, :string, default: 'ofn@example.com'
|
||||
preference :intercept_email, :string, default: nil
|
||||
|
||||
# Default smtp settings
|
||||
preference :override_actionmailer_config, :boolean, default: true
|
||||
preference :mail_host, :string, default: 'localhost'
|
||||
preference :mail_domain, :string, default: 'localhost'
|
||||
preference :mail_port, :integer, default: 25
|
||||
|
||||
@@ -79,11 +79,17 @@ module Spree
|
||||
end
|
||||
|
||||
def actions
|
||||
%w{capture void credit}
|
||||
%w{capture void credit resend_authorization_email}
|
||||
end
|
||||
|
||||
def can_resend_authorization_email?(payment)
|
||||
payment.pending? && payment.cvv_response_message.present?
|
||||
end
|
||||
|
||||
# Indicates whether its possible to capture the payment
|
||||
def can_capture?(payment)
|
||||
return false if payment.cvv_response_message.present?
|
||||
|
||||
payment.pending? || payment.checkout?
|
||||
end
|
||||
|
||||
|
||||
@@ -45,6 +45,11 @@ module Spree
|
||||
failed_activemerchant_billing_response(e.message)
|
||||
end
|
||||
|
||||
def capture(money, payment_intent_id, gateway_options)
|
||||
options = basic_options(gateway_options)
|
||||
provider.capture(money, payment_intent_id, options)
|
||||
end
|
||||
|
||||
# NOTE: the name of this method is determined by Spree::Payment::Processing
|
||||
def charge_offline(money, creditcard, gateway_options)
|
||||
customer, payment_method =
|
||||
@@ -110,7 +115,7 @@ module Spree
|
||||
|
||||
def options_for_authorize(money, creditcard, gateway_options)
|
||||
options = basic_options(gateway_options)
|
||||
options[:return_url] = full_checkout_path
|
||||
options[:return_url] = gateway_options[:return_url] || full_checkout_path
|
||||
|
||||
customer_id, payment_method_id =
|
||||
Stripe::CreditCardCloner.new(creditcard, stripe_account_id).find_or_clone
|
||||
|
||||
8
app/models/spree/option_values_line_item.rb
Normal file
8
app/models/spree/option_values_line_item.rb
Normal file
@@ -0,0 +1,8 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Spree
|
||||
class OptionValuesLineItem < ActiveRecord::Base
|
||||
belongs_to :line_item, class_name: 'Spree::LineItem'
|
||||
belongs_to :option_value, class_name: 'Spree::OptionValue'
|
||||
end
|
||||
end
|
||||
@@ -130,6 +130,11 @@ module Spree
|
||||
where("state != ?", state)
|
||||
}
|
||||
|
||||
# All the states an order can be in after completing the checkout
|
||||
FINALIZED_STATES = %w(complete canceled resumed awaiting_return returned).freeze
|
||||
|
||||
scope :finalized, -> { where(state: FINALIZED_STATES) }
|
||||
|
||||
def self.by_number(number)
|
||||
where(number: number)
|
||||
end
|
||||
@@ -387,11 +392,11 @@ module Spree
|
||||
end
|
||||
|
||||
def ship_total
|
||||
adjustments.shipping.map(&:amount).sum
|
||||
adjustments.shipping.sum(:amount)
|
||||
end
|
||||
|
||||
def tax_total
|
||||
adjustments.tax.map(&:amount).sum
|
||||
adjustments.tax.sum(:amount)
|
||||
end
|
||||
|
||||
# Creates new tax charges if there are any applicable rates. If prices already
|
||||
@@ -723,15 +728,7 @@ module Spree
|
||||
end
|
||||
|
||||
def total_tax
|
||||
(adjustments.to_a + price_adjustments.to_a).sum(&:included_tax)
|
||||
end
|
||||
|
||||
def price_adjustments
|
||||
adjustments = []
|
||||
|
||||
line_items.each { |line_item| adjustments.concat line_item.adjustments }
|
||||
|
||||
adjustments
|
||||
(adjustments.to_a + line_item_adjustments.to_a).sum(&:included_tax)
|
||||
end
|
||||
|
||||
def price_adjustment_totals
|
||||
|
||||
@@ -121,6 +121,12 @@ module Spree
|
||||
actions
|
||||
end
|
||||
|
||||
def resend_authorization_email!
|
||||
return unless cvv_response_message.present?
|
||||
|
||||
PaymentMailer.authorize_payment(self).deliver_later
|
||||
end
|
||||
|
||||
def payment_source
|
||||
res = source.is_a?(Payment) ? source.source : source
|
||||
res || payment_method
|
||||
|
||||
@@ -23,9 +23,9 @@ module Spree
|
||||
end
|
||||
end
|
||||
|
||||
def authorize!
|
||||
def authorize!(return_url = nil)
|
||||
started_processing!
|
||||
gateway_action(source, :authorize, :pend)
|
||||
gateway_action(source, :authorize, :pend, return_url: return_url)
|
||||
end
|
||||
|
||||
def purchase!
|
||||
@@ -44,19 +44,7 @@ module Spree
|
||||
started_processing!
|
||||
protect_from_connection_error do
|
||||
check_environment
|
||||
|
||||
response = if payment_method.payment_profiles_supported?
|
||||
# Gateways supporting payment profiles will need access to credit
|
||||
# card object because this stores the payment profile information
|
||||
# so supply the authorization itself as well as the credit card,
|
||||
# rather than just the authorization code
|
||||
payment_method.capture(self, source, gateway_options)
|
||||
else
|
||||
# Standard ActiveMerchant capture usage
|
||||
payment_method.capture(money.money.cents,
|
||||
response_code,
|
||||
gateway_options)
|
||||
end
|
||||
response = payment_method.capture(money.money.cents, response_code, gateway_options)
|
||||
|
||||
handle_response(response, :complete, :failure)
|
||||
end
|
||||
@@ -222,7 +210,7 @@ module Spree
|
||||
refund_amount.to_f
|
||||
end
|
||||
|
||||
def gateway_action(source, action, success_state)
|
||||
def gateway_action(source, action, success_state, options = {})
|
||||
protect_from_connection_error do
|
||||
check_environment
|
||||
|
||||
@@ -230,7 +218,7 @@ module Spree
|
||||
action,
|
||||
(amount * 100).round,
|
||||
source,
|
||||
gateway_options
|
||||
gateway_options.merge(options)
|
||||
)
|
||||
handle_response(response, success_state, :failure)
|
||||
end
|
||||
|
||||
@@ -1,138 +0,0 @@
|
||||
class Spree::ProductSet < ModelSet
|
||||
def initialize(attributes = {})
|
||||
super(Spree::Product, [], attributes)
|
||||
end
|
||||
|
||||
def save
|
||||
@collection_hash.each_value.all? do |product_attributes|
|
||||
update_product_attributes(product_attributes)
|
||||
end
|
||||
end
|
||||
|
||||
def collection_attributes=(attributes)
|
||||
@collection = Spree::Product
|
||||
.where(id: attributes.each_value.map { |product| product[:id] })
|
||||
@collection_hash = attributes
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# A separate method of updating products was required due to an issue with
|
||||
# the way Rails' assign_attributes and update behave when
|
||||
# delegated attributes of a nested object are updated via the parent object
|
||||
# (ie. price of variants). Updating such attributes by themselves did not
|
||||
# work using:
|
||||
#
|
||||
# product.update(variants_attributes: [{ id: y, price: xx.x }])
|
||||
#
|
||||
# and so an explicit call to update on each individual variant was
|
||||
# required. ie:
|
||||
#
|
||||
# variant.update( { price: xx.x } )
|
||||
#
|
||||
def update_product_attributes(attributes)
|
||||
split_taxon_ids!(attributes)
|
||||
|
||||
product = find_model(@collection, attributes[:id])
|
||||
return if product.nil?
|
||||
|
||||
update_product(product, attributes)
|
||||
end
|
||||
|
||||
def split_taxon_ids!(attributes)
|
||||
attributes[:taxon_ids] = attributes[:taxon_ids].split(',') if attributes[:taxon_ids].present?
|
||||
end
|
||||
|
||||
def update_product(product, attributes)
|
||||
original_supplier = product.supplier_id
|
||||
return false unless update_product_only_attributes(product, attributes)
|
||||
|
||||
ExchangeVariantDeleter.new.delete(product) if original_supplier != product.supplier_id
|
||||
|
||||
update_product_variants(product, attributes) &&
|
||||
update_product_master(product, attributes)
|
||||
end
|
||||
|
||||
def update_product_only_attributes(product, attributes)
|
||||
variant_related_attrs = [:id, :variants_attributes, :master_attributes]
|
||||
product_related_attrs = attributes.except(*variant_related_attrs)
|
||||
return true if product_related_attrs.blank?
|
||||
|
||||
product.assign_attributes(product_related_attrs)
|
||||
|
||||
validate_presence_of_unit_value_in_product(product)
|
||||
|
||||
product.errors.empty? && product.save
|
||||
end
|
||||
|
||||
def validate_presence_of_unit_value_in_product(product)
|
||||
product.variants.each do |variant|
|
||||
validate_presence_of_unit_value_in_variant(product, variant)
|
||||
end
|
||||
end
|
||||
|
||||
def validate_presence_of_unit_value_in_variant(product, variant)
|
||||
return unless %w(weight volume).include?(product.variant_unit)
|
||||
return if variant.unit_value.present?
|
||||
|
||||
product.errors.add(:unit_value, "can't be blank")
|
||||
end
|
||||
|
||||
def update_product_variants(product, attributes)
|
||||
return true unless attributes[:variants_attributes]
|
||||
|
||||
update_variants_attributes(product, attributes[:variants_attributes])
|
||||
end
|
||||
|
||||
def update_product_master(product, attributes)
|
||||
return true unless attributes[:master_attributes]
|
||||
|
||||
create_or_update_variant(product, attributes[:master_attributes])
|
||||
end
|
||||
|
||||
def update_variants_attributes(product, variants_attributes)
|
||||
variants_attributes.each do |attributes|
|
||||
create_or_update_variant(product, attributes)
|
||||
end
|
||||
end
|
||||
|
||||
def create_or_update_variant(product, variant_attributes)
|
||||
variant = find_model(product.variants_including_master, variant_attributes[:id])
|
||||
if variant.present?
|
||||
variant.update(variant_attributes.except(:id))
|
||||
else
|
||||
create_variant(product, variant_attributes)
|
||||
end
|
||||
end
|
||||
|
||||
def create_variant(product, variant_attributes)
|
||||
on_hand = variant_attributes.delete(:on_hand)
|
||||
on_demand = variant_attributes.delete(:on_demand)
|
||||
|
||||
variant = product.variants.create(variant_attributes)
|
||||
|
||||
begin
|
||||
variant.on_demand = on_demand if on_demand.present?
|
||||
variant.on_hand = on_hand.to_i if on_hand.present?
|
||||
rescue StandardError => e
|
||||
notify_bugsnag(e, product, variant, variant_attributes)
|
||||
raise e
|
||||
end
|
||||
end
|
||||
|
||||
def notify_bugsnag(error, product, variant, variant_attributes)
|
||||
Bugsnag.notify(error) do |report|
|
||||
report.add_tab(:product, product.attributes)
|
||||
report.add_tab(:product_error, product.errors.first) unless product.valid?
|
||||
report.add_tab(:variant_attributes, variant_attributes)
|
||||
report.add_tab(:variant, variant.attributes)
|
||||
report.add_tab(:variant_error, variant.errors.first) unless variant.valid?
|
||||
end
|
||||
end
|
||||
|
||||
def find_model(collection, model_id)
|
||||
collection.find do |model|
|
||||
model.id.to_s == model_id.to_s && model.persisted?
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -249,8 +249,11 @@ module Spree
|
||||
|
||||
def to_package
|
||||
package = OrderManagement::Stock::Package.new(stock_location, order)
|
||||
inventory_units.includes(:variant).each do |inventory_unit|
|
||||
package.add inventory_unit.variant, 1, inventory_unit.state_name
|
||||
grouped_inventory_units = inventory_units.includes(:variant).group_by do |iu|
|
||||
[iu.variant, iu.state_name]
|
||||
end
|
||||
grouped_inventory_units.each do |(variant, state_name), inventory_units|
|
||||
package.add variant, inventory_units.count, state_name
|
||||
end
|
||||
package
|
||||
end
|
||||
|
||||
@@ -71,6 +71,7 @@ module Spree
|
||||
amount: amount,
|
||||
source: order,
|
||||
originator: self,
|
||||
order: order,
|
||||
state: "closed",
|
||||
label: label
|
||||
)
|
||||
@@ -82,8 +83,8 @@ module Spree
|
||||
order.adjustments(:reload)
|
||||
order.line_items(:reload)
|
||||
# TaxRate adjustments (order.adjustments.tax)
|
||||
# and price adjustments (tax included on line items) consist of 100% tax
|
||||
(order.adjustments.tax + order.price_adjustments).each do |adjustment|
|
||||
# and line item adjustments (tax included on line items) consist of 100% tax
|
||||
(order.adjustments.tax + order.line_item_adjustments.reload).each do |adjustment|
|
||||
adjustment.set_absolute_included_tax! adjustment.amount
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
class VariantOverrideSet < ModelSet
|
||||
def initialize(collection, attributes = {})
|
||||
super(VariantOverride, collection, attributes, nil, proc { |attrs, tag_list| deletable?(attrs, tag_list) } )
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def deletable?(attrs, tag_list)
|
||||
attrs['price'].blank? &&
|
||||
attrs['count_on_hand'].blank? &&
|
||||
attrs['default_stock'].blank? &&
|
||||
attrs['resettable'].blank? &&
|
||||
attrs['sku'].nil? &&
|
||||
attrs['on_demand'].nil? &&
|
||||
tag_list.empty?
|
||||
end
|
||||
|
||||
# Override of ModelSet method to allow us to check presence of a tag_list (which is not an attribute)
|
||||
# This method will delete VariantOverrides that have no values (see deletable? above)
|
||||
# If the user sets all values to nil in the UI the VO will be deleted from the DB
|
||||
def collection_to_delete
|
||||
deleted = []
|
||||
collection.delete_if { |e| deleted << e if @delete_if.andand.call(e.attributes, e.tag_list) }
|
||||
deleted
|
||||
end
|
||||
|
||||
def collection_to_keep
|
||||
collection.reject { |e| @delete_if.andand.call(e.attributes, e.tag_list) }
|
||||
end
|
||||
end
|
||||
21
app/queries/complete_orders_with_balance.rb
Normal file
21
app/queries/complete_orders_with_balance.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Fetches complete orders of the specified user including their balance as a computed column
|
||||
class CompleteOrdersWithBalance
|
||||
def initialize(user)
|
||||
@user = user
|
||||
end
|
||||
|
||||
def query
|
||||
OutstandingBalance.new(sorted_finalized_orders).query
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def sorted_finalized_orders
|
||||
@user.orders
|
||||
.finalized
|
||||
.select('spree_orders.*')
|
||||
.order(completed_at: :desc)
|
||||
end
|
||||
end
|
||||
39
app/queries/customers_with_balance.rb
Normal file
39
app/queries/customers_with_balance.rb
Normal file
@@ -0,0 +1,39 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Fetches the customers of the specified enterprise including the aggregated balance across the
|
||||
# customer's orders. That is, we get the total balance for each customer with this enterprise.
|
||||
class CustomersWithBalance
|
||||
def initialize(enterprise)
|
||||
@enterprise = enterprise
|
||||
end
|
||||
|
||||
def query
|
||||
Customer.of(enterprise).
|
||||
joins(left_join_complete_orders).
|
||||
group("customers.id").
|
||||
select("customers.*").
|
||||
select(outstanding_balance_sum)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :enterprise
|
||||
|
||||
def outstanding_balance_sum
|
||||
"SUM(#{OutstandingBalance.new.statement}) AS balance_value"
|
||||
end
|
||||
|
||||
# The resulting orders are in states that belong after the checkout. Only these can be considered
|
||||
# for a customer's balance.
|
||||
def left_join_complete_orders
|
||||
<<-SQL.strip_heredoc
|
||||
LEFT JOIN spree_orders ON spree_orders.customer_id = customers.id
|
||||
AND #{finalized_states.to_sql}
|
||||
SQL
|
||||
end
|
||||
|
||||
def finalized_states
|
||||
states = Spree::Order::FINALIZED_STATES.map { |state| Arel::Nodes.build_quoted(state) }
|
||||
Arel::Nodes::In.new(Spree::Order.arel_table[:state], states)
|
||||
end
|
||||
end
|
||||
44
app/queries/outstanding_balance.rb
Normal file
44
app/queries/outstanding_balance.rb
Normal file
@@ -0,0 +1,44 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Encapsulates the SQL statement that computes the balance of an order as a new column in the result
|
||||
# set. This can then be reused chaining it with the ActiveRecord::Relation objects you pass in the
|
||||
# constructor.
|
||||
#
|
||||
# Alternatively, you can get the SQL by calling #statement, which is suitable for more complex
|
||||
# cases.
|
||||
#
|
||||
# See CompleteOrdersWithBalance or CustomersWithBalance as examples.
|
||||
class OutstandingBalance
|
||||
# All the states of a finished order but that shouldn't count towards the balance (the customer
|
||||
# didn't get the order for whatever reason). Note it does not include complete
|
||||
FINALIZED_NON_SUCCESSFUL_STATES = %w(canceled returned).freeze
|
||||
|
||||
# The relation must be an ActiveRecord::Relation object with `spree_orders` in the SQL statement
|
||||
# FROM for #statement to work.
|
||||
def initialize(relation = nil)
|
||||
@relation = relation
|
||||
end
|
||||
|
||||
def query
|
||||
relation.select("#{statement} AS balance_value")
|
||||
end
|
||||
|
||||
# Arel doesn't support CASE statements until v7.1.0 so we'll have to wait with SQL literals
|
||||
# a little longer. See https://github.com/rails/arel/pull/400 for details.
|
||||
def statement
|
||||
<<-SQL.strip_heredoc
|
||||
CASE WHEN state IN #{non_fulfilled_states_group.to_sql} THEN payment_total
|
||||
WHEN state IS NOT NULL THEN payment_total - total
|
||||
ELSE 0 END
|
||||
SQL
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :relation
|
||||
|
||||
def non_fulfilled_states_group
|
||||
states = FINALIZED_NON_SUCCESSFUL_STATES.map { |state| Arel::Nodes.build_quoted(state) }
|
||||
Arel::Nodes::Grouping.new(states)
|
||||
end
|
||||
end
|
||||
@@ -7,6 +7,14 @@ module Api
|
||||
|
||||
has_many :payments, serializer: Api::PaymentSerializer
|
||||
|
||||
def outstanding_balance
|
||||
if OpenFoodNetwork::FeatureToggle.enabled?(:customer_balance, object.user)
|
||||
-object.balance_value
|
||||
else
|
||||
object.outstanding_balance
|
||||
end
|
||||
end
|
||||
|
||||
def payments
|
||||
object.payments.joins(:payment_method).completed
|
||||
end
|
||||
@@ -42,13 +50,13 @@ module Api
|
||||
end
|
||||
|
||||
def path
|
||||
Spree::Core::Engine.routes.url_helpers.order_path(object)
|
||||
order_path(object)
|
||||
end
|
||||
|
||||
def cancel_path
|
||||
return nil unless object.changes_allowed?
|
||||
|
||||
Spree::Core::Engine.routes.url_helpers.cancel_order_path(object)
|
||||
cancel_order_path(object)
|
||||
end
|
||||
|
||||
def changes_allowed
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
require 'open_food_network/scope_variant_to_hub'
|
||||
|
||||
# Previously Spree::OrderPopulator. Modified to work with max_quantity and variant overrides.
|
||||
|
||||
class CartService
|
||||
attr_accessor :order, :currency
|
||||
attr_reader :variants_h
|
||||
|
||||
17
app/services/customer_order_cancellation.rb
Normal file
17
app/services/customer_order_cancellation.rb
Normal file
@@ -0,0 +1,17 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class CustomerOrderCancellation
|
||||
def initialize(order)
|
||||
@order = order
|
||||
end
|
||||
|
||||
def call
|
||||
return unless order.cancel
|
||||
|
||||
Spree::OrderMailer.cancel_email_for_shop(order).deliver_later
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :order
|
||||
end
|
||||
@@ -1,61 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class CustomersWithBalance
|
||||
def initialize(enterprise)
|
||||
@enterprise = enterprise
|
||||
end
|
||||
|
||||
def query
|
||||
Customer.of(enterprise).
|
||||
joins(left_join_complete_orders).
|
||||
group("customers.id").
|
||||
select("customers.*").
|
||||
select(outstanding_balance)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :enterprise
|
||||
|
||||
# Arel doesn't support CASE statements until v7.1.0 so we'll have to wait with SQL literals
|
||||
# a little longer. See https://github.com/rails/arel/pull/400 for details.
|
||||
def outstanding_balance
|
||||
<<-SQL.strip_heredoc
|
||||
SUM(
|
||||
CASE WHEN state IN #{non_fulfilled_states_group.to_sql} THEN payment_total
|
||||
WHEN state IS NOT NULL THEN payment_total - total
|
||||
ELSE 0 END
|
||||
) AS balance_value
|
||||
SQL
|
||||
end
|
||||
|
||||
# The resulting orders are in states that belong after the checkout. Only these can be considered
|
||||
# for a customer's balance.
|
||||
def left_join_complete_orders
|
||||
<<-SQL.strip_heredoc
|
||||
LEFT JOIN spree_orders ON spree_orders.customer_id = customers.id
|
||||
AND #{complete_orders.to_sql}
|
||||
SQL
|
||||
end
|
||||
|
||||
def complete_orders
|
||||
states_group = prior_to_completion_states.map { |state| Arel::Nodes.build_quoted(state) }
|
||||
Arel::Nodes::NotIn.new(Spree::Order.arel_table[:state], states_group)
|
||||
end
|
||||
|
||||
def non_fulfilled_states_group
|
||||
states_group = non_fulfilled_states.map { |state| Arel::Nodes.build_quoted(state) }
|
||||
Arel::Nodes::Grouping.new(states_group)
|
||||
end
|
||||
|
||||
# All the states an order can be in before completing the checkout
|
||||
def prior_to_completion_states
|
||||
%w(cart address delivery payment)
|
||||
end
|
||||
|
||||
# All the states of a complete order but that shouldn't count towards the balance. Those that the
|
||||
# customer won't enjoy.
|
||||
def non_fulfilled_states
|
||||
%w(canceled returned)
|
||||
end
|
||||
end
|
||||
9
app/services/sets/column_preference_set.rb
Normal file
9
app/services/sets/column_preference_set.rb
Normal file
@@ -0,0 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Sets
|
||||
class ColumnPreferenceSet < ModelSet
|
||||
def initialize(collection, attributes = {})
|
||||
super(ColumnPreference, collection, attributes, nil, nil )
|
||||
end
|
||||
end
|
||||
end
|
||||
11
app/services/sets/enterprise_fee_set.rb
Normal file
11
app/services/sets/enterprise_fee_set.rb
Normal file
@@ -0,0 +1,11 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Sets
|
||||
class EnterpriseFeeSet < ModelSet
|
||||
def initialize(attributes = {})
|
||||
super(EnterpriseFee, EnterpriseFee.all,
|
||||
attributes,
|
||||
proc { |attrs| attrs[:name].blank? })
|
||||
end
|
||||
end
|
||||
end
|
||||
9
app/services/sets/enterprise_set.rb
Normal file
9
app/services/sets/enterprise_set.rb
Normal file
@@ -0,0 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Sets
|
||||
class EnterpriseSet < ModelSet
|
||||
def initialize(collection, attributes = {})
|
||||
super(Enterprise, collection, attributes)
|
||||
end
|
||||
end
|
||||
end
|
||||
69
app/services/sets/model_set.rb
Normal file
69
app/services/sets/model_set.rb
Normal file
@@ -0,0 +1,69 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Tableless model to handle updating multiple models at once from a single form
|
||||
module Sets
|
||||
class ModelSet
|
||||
include ActiveModel::Conversion
|
||||
extend ActiveModel::Naming
|
||||
|
||||
attr_accessor :collection
|
||||
|
||||
def initialize(klass, collection, attributes = {}, reject_if = nil, delete_if = nil)
|
||||
@klass, @collection, @reject_if, @delete_if = klass, collection, reject_if, delete_if
|
||||
|
||||
# Set here first, to ensure that we apply collection_attributes to the right collection
|
||||
@collection = attributes[:collection] if attributes[:collection]
|
||||
|
||||
attributes.each do |name, value|
|
||||
public_send("#{name}=", value)
|
||||
end
|
||||
end
|
||||
|
||||
def collection_attributes=(collection_attributes)
|
||||
collection_attributes.each do |_k, attributes|
|
||||
# attributes == {:id => 123, :next_collection_at => '...'}
|
||||
found_element = @collection.detect do |element|
|
||||
element.id.to_s == attributes[:id].to_s && !element.id.nil?
|
||||
end
|
||||
|
||||
if found_element.nil?
|
||||
@collection << @klass.new(attributes) unless @reject_if.andand.call(attributes)
|
||||
else
|
||||
found_element.assign_attributes(attributes.except(:id))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def errors
|
||||
errors = ActiveModel::Errors.new self
|
||||
full_messages = @collection
|
||||
.map { |model| model.errors.full_messages }
|
||||
.flatten
|
||||
|
||||
full_messages.each { |message| errors.add(:base, message) }
|
||||
errors
|
||||
end
|
||||
|
||||
def save
|
||||
collection_to_delete.each(&:destroy)
|
||||
collection_to_keep.all?(&:save)
|
||||
end
|
||||
|
||||
def collection_to_delete
|
||||
# Remove all elements to be deleted from collection and return them
|
||||
# Allows us to render @model_set.collection without deleted elements
|
||||
deleted = []
|
||||
@collection = collection.to_a
|
||||
collection.delete_if { |e| deleted << e if @delete_if.andand.call(e.attributes) }
|
||||
deleted
|
||||
end
|
||||
|
||||
def collection_to_keep
|
||||
collection.reject { |e| @delete_if.andand.call(e.attributes) }
|
||||
end
|
||||
|
||||
def persisted?
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
9
app/services/sets/order_cycle_set.rb
Normal file
9
app/services/sets/order_cycle_set.rb
Normal file
@@ -0,0 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Sets
|
||||
class OrderCycleSet < ModelSet
|
||||
def initialize(collection, attributes = {})
|
||||
super(OrderCycle, collection, attributes)
|
||||
end
|
||||
end
|
||||
end
|
||||
142
app/services/sets/product_set.rb
Normal file
142
app/services/sets/product_set.rb
Normal file
@@ -0,0 +1,142 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Sets
|
||||
class ProductSet < ModelSet
|
||||
def initialize(attributes = {})
|
||||
super(Spree::Product, [], attributes)
|
||||
end
|
||||
|
||||
def save
|
||||
@collection_hash.each_value.all? do |product_attributes|
|
||||
update_product_attributes(product_attributes)
|
||||
end
|
||||
end
|
||||
|
||||
def collection_attributes=(attributes)
|
||||
@collection = Spree::Product
|
||||
.where(id: attributes.each_value.map { |product| product[:id] })
|
||||
@collection_hash = attributes
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# A separate method of updating products was required due to an issue with
|
||||
# the way Rails' assign_attributes and update behave when
|
||||
# delegated attributes of a nested object are updated via the parent object
|
||||
# (ie. price of variants). Updating such attributes by themselves did not
|
||||
# work using:
|
||||
#
|
||||
# product.update(variants_attributes: [{ id: y, price: xx.x }])
|
||||
#
|
||||
# and so an explicit call to update on each individual variant was
|
||||
# required. ie:
|
||||
#
|
||||
# variant.update( { price: xx.x } )
|
||||
#
|
||||
def update_product_attributes(attributes)
|
||||
split_taxon_ids!(attributes)
|
||||
|
||||
product = find_model(@collection, attributes[:id])
|
||||
return if product.nil?
|
||||
|
||||
update_product(product, attributes)
|
||||
end
|
||||
|
||||
def split_taxon_ids!(attributes)
|
||||
attributes[:taxon_ids] = attributes[:taxon_ids].split(',') if attributes[:taxon_ids].present?
|
||||
end
|
||||
|
||||
def update_product(product, attributes)
|
||||
original_supplier = product.supplier_id
|
||||
return false unless update_product_only_attributes(product, attributes)
|
||||
|
||||
ExchangeVariantDeleter.new.delete(product) if original_supplier != product.supplier_id
|
||||
|
||||
update_product_variants(product, attributes) &&
|
||||
update_product_master(product, attributes)
|
||||
end
|
||||
|
||||
def update_product_only_attributes(product, attributes)
|
||||
variant_related_attrs = [:id, :variants_attributes, :master_attributes]
|
||||
product_related_attrs = attributes.except(*variant_related_attrs)
|
||||
return true if product_related_attrs.blank?
|
||||
|
||||
product.assign_attributes(product_related_attrs)
|
||||
|
||||
validate_presence_of_unit_value_in_product(product)
|
||||
|
||||
product.errors.empty? && product.save
|
||||
end
|
||||
|
||||
def validate_presence_of_unit_value_in_product(product)
|
||||
product.variants.each do |variant|
|
||||
validate_presence_of_unit_value_in_variant(product, variant)
|
||||
end
|
||||
end
|
||||
|
||||
def validate_presence_of_unit_value_in_variant(product, variant)
|
||||
return unless %w(weight volume).include?(product.variant_unit)
|
||||
return if variant.unit_value.present?
|
||||
|
||||
product.errors.add(:unit_value, "can't be blank")
|
||||
end
|
||||
|
||||
def update_product_variants(product, attributes)
|
||||
return true unless attributes[:variants_attributes]
|
||||
|
||||
update_variants_attributes(product, attributes[:variants_attributes])
|
||||
end
|
||||
|
||||
def update_product_master(product, attributes)
|
||||
return true unless attributes[:master_attributes]
|
||||
|
||||
create_or_update_variant(product, attributes[:master_attributes])
|
||||
end
|
||||
|
||||
def update_variants_attributes(product, variants_attributes)
|
||||
variants_attributes.each do |attributes|
|
||||
create_or_update_variant(product, attributes)
|
||||
end
|
||||
end
|
||||
|
||||
def create_or_update_variant(product, variant_attributes)
|
||||
variant = find_model(product.variants_including_master, variant_attributes[:id])
|
||||
if variant.present?
|
||||
variant.update(variant_attributes.except(:id))
|
||||
else
|
||||
create_variant(product, variant_attributes)
|
||||
end
|
||||
end
|
||||
|
||||
def create_variant(product, variant_attributes)
|
||||
on_hand = variant_attributes.delete(:on_hand)
|
||||
on_demand = variant_attributes.delete(:on_demand)
|
||||
|
||||
variant = product.variants.create(variant_attributes)
|
||||
|
||||
begin
|
||||
variant.on_demand = on_demand if on_demand.present?
|
||||
variant.on_hand = on_hand.to_i if on_hand.present?
|
||||
rescue StandardError => e
|
||||
notify_bugsnag(e, product, variant, variant_attributes)
|
||||
raise e
|
||||
end
|
||||
end
|
||||
|
||||
def notify_bugsnag(error, product, variant, variant_attributes)
|
||||
Bugsnag.notify(error) do |report|
|
||||
report.add_tab(:product, product.attributes)
|
||||
report.add_tab(:product_error, product.errors.first) unless product.valid?
|
||||
report.add_tab(:variant_attributes, variant_attributes)
|
||||
report.add_tab(:variant, variant.attributes)
|
||||
report.add_tab(:variant_error, variant.errors.first) unless variant.valid?
|
||||
end
|
||||
end
|
||||
|
||||
def find_model(collection, model_id)
|
||||
collection.find do |model|
|
||||
model.id.to_s == model_id.to_s && model.persisted?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
38
app/services/sets/variant_override_set.rb
Normal file
38
app/services/sets/variant_override_set.rb
Normal file
@@ -0,0 +1,38 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Sets
|
||||
class VariantOverrideSet < ModelSet
|
||||
def initialize(collection, attributes = {})
|
||||
super(VariantOverride,
|
||||
collection,
|
||||
attributes,
|
||||
nil,
|
||||
proc { |attrs, tag_list| deletable?(attrs, tag_list) } )
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def deletable?(attrs, tag_list)
|
||||
attrs['price'].blank? &&
|
||||
attrs['count_on_hand'].blank? &&
|
||||
attrs['default_stock'].blank? &&
|
||||
attrs['resettable'].blank? &&
|
||||
attrs['sku'].nil? &&
|
||||
attrs['on_demand'].nil? &&
|
||||
tag_list.empty?
|
||||
end
|
||||
|
||||
# Overrides ModelSet method to check presence of a tag_list (which is not an attribute)
|
||||
# This method will delete VariantOverrides that have no values (see deletable? above)
|
||||
# If the user sets all values to nil in the UI the VO will be deleted from the DB
|
||||
def collection_to_delete
|
||||
deleted = []
|
||||
collection.delete_if { |e| deleted << e if @delete_if.andand.call(e.attributes, e.tag_list) }
|
||||
deleted
|
||||
end
|
||||
|
||||
def collection_to_keep
|
||||
collection.reject { |e| @delete_if.andand.call(e.attributes, e.tag_list) }
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
.row{ 'ng-if' => 'shop_id && RequestMonitor.loading' }
|
||||
.sixteen.columns.alpha#loading
|
||||
%img.spinner{ src: image_path("spinning-circles.svg") }
|
||||
= render partial: "components/spinner"
|
||||
%h1
|
||||
=t :loading_customers
|
||||
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
-# Render only the calculator settings and not the surrounding form
|
||||
- enterprise_fee_set = ModelSet.new(EnterpriseFee, EnterpriseFee.where(:id => enterprise_fee.id))
|
||||
- enterprise_fee_set = Sets::ModelSet.new(EnterpriseFee, EnterpriseFee.where(:id => enterprise_fee.id))
|
||||
- calculator_form_string = nil
|
||||
- form_for enterprise_fee_set, :as => :enterprise_fee_set, :url => '' do |form|
|
||||
- form_for enterprise_fee_set, :as => :sets_enterprise_fee_set, :url => '' do |form|
|
||||
- form.fields_for :collection do |f|
|
||||
- calculator_form_string = capture do
|
||||
- if !enterprise_fee.new_record?
|
||||
.calculator-settings
|
||||
= f.fields_for :calculator do |calculator_form|
|
||||
- preference_fields(enterprise_fee.calculator, calculator_form).each do |field|
|
||||
.field.alpha.one.columns
|
||||
%span.field
|
||||
= field[:label]
|
||||
.field.omega.two.columns
|
||||
%p.field
|
||||
= field[:field]
|
||||
|
||||
= calculator_form_string
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
.four.columns.alpha
|
||||
= render 'admin/shared/side_menu'
|
||||
.one.column
|
||||
.eleven.columns.omega.fullwidth_inputs
|
||||
.eight.columns.omega.fullwidth_inputs
|
||||
= render 'form_primary_details', f: f
|
||||
= render 'form_users', f: f
|
||||
= render 'form_about', f: f
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
%input{ hidden: "true", name: "sells", ng: { required: true, pattern: "/^(none|own|any)$/", model: 'sells', value: "sells"} }
|
||||
|
||||
.row
|
||||
.options.sixteen.columns.alpha
|
||||
.options.container
|
||||
- if @enterprise.is_primary_producer
|
||||
.basic_producer.option.one-third.column.alpha
|
||||
.basic_producer.option.six.columns.alpha
|
||||
%a.full-width.button.selector{ ng: { click: "sells='none'", class: "{selected: sells=='none'}" } }
|
||||
.top
|
||||
%h3= t('.producer_profile')
|
||||
@@ -17,7 +17,7 @@
|
||||
%p.description
|
||||
= t('.producer_description_text')
|
||||
|
||||
.producer_shop.option.one-third.column
|
||||
.producer_shop.option.six.columns
|
||||
%a.full-width.button.selector{ ng: { click: "sells='own'", class: "{selected: sells=='own'}" } }
|
||||
.top
|
||||
%h3= t('.producer_shop')
|
||||
@@ -28,7 +28,7 @@
|
||||
%br
|
||||
= t('.producer_shop_description_text2')
|
||||
|
||||
.full_hub.option.one-third.column.omega
|
||||
.full_hub.option.six.columns.omega
|
||||
%a.full-width.button.selector{ ng: { click: "sells='any'", class: "{selected: sells=='any'}" } }
|
||||
.top
|
||||
%h3= t('.producer_hub')
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
%columns-dropdown{ action: "#{controller_name}_#{action_name}" }
|
||||
.row{ 'ng-if' => '!loaded' }
|
||||
.sixteen.columns.alpha#loading
|
||||
%img.spinner{ src: image_path("spinning-circles.svg") }
|
||||
= render partial: "components/spinner"
|
||||
%h1= t('.loading_enterprises')
|
||||
.row{ :class => "sixteen columns alpha", 'ng-show' => 'loaded && filteredEnterprises.length == 0'}
|
||||
%h1#no_results= t('.no_enterprises_found')
|
||||
|
||||
@@ -31,8 +31,7 @@
|
||||
\/
|
||||
= af.label :country_id, t(:country)
|
||||
%span.required *
|
||||
%div{ "ng-controller" => "countryCtrl" }
|
||||
.four.columns
|
||||
%input.ofn-select2.fullwidth#enterprise_address_attributes_state_id{ name: 'enterprise[address_attributes][state_id]', type: 'number', data: 'countriesById[Enterprise.address.country_id].states', placeholder: t('admin.choose'), ng: { model: 'Enterprise.address.state_id' } }
|
||||
.four.columns.omega
|
||||
%input.ofn-select2.fullwidth#enterprise_address_attributes_country_id{ name: 'enterprise[address_attributes][country_id]', type: 'number', data: 'countries', placeholder: t('admin.choose'), ng: { model: 'Enterprise.address.country_id' } }
|
||||
.four.columns{ "ng-controller" => "countryCtrl" }
|
||||
%input.ofn-select2.fullwidth#enterprise_address_attributes_state_id{ name: 'enterprise[address_attributes][state_id]', type: 'number', data: 'countriesById[Enterprise.address.country_id].states', placeholder: t('admin.choose'), ng: { model: 'Enterprise.address.state_id' } }
|
||||
.four.columns.omega{ "ng-controller" => "countryCtrl" }
|
||||
%input.ofn-select2.fullwidth#enterprise_address_attributes_country_id{ name: 'enterprise[address_attributes][country_id]', type: 'number', data: 'countries', placeholder: t('admin.choose'), ng: { model: 'Enterprise.address.country_id' } }
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
%td= link_to t(:edit), edit_admin_payment_method_path(payment_method)
|
||||
%br
|
||||
.row
|
||||
.six.columns.alpha
|
||||
.eight.columns
|
||||
%a.button{ href: "#{admin_payment_methods_path}"}
|
||||
= t('.manage')
|
||||
%i.icon-arrow-right
|
||||
.five.columns.omega.text-right
|
||||
.eight.columns.text-right
|
||||
%a.button{ href: "#{new_admin_payment_method_path}"}
|
||||
= t('.create_button')
|
||||
%i.icon-plus
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
.row
|
||||
.alpha.eleven.columns
|
||||
.three.columns.alpha
|
||||
= f.label :name, t('.name')
|
||||
%span.required *
|
||||
.eight.columns.omega
|
||||
= f.text_field :name, { placeholder: t('.name_placeholder') }
|
||||
.three.columns.alpha
|
||||
= f.label :name, t('.name')
|
||||
%span.required *
|
||||
.eight.columns.omega
|
||||
= f.text_field :name, { placeholder: t('.name_placeholder') }
|
||||
- if @groups.present?
|
||||
.row
|
||||
.alpha.eleven.columns
|
||||
.three.columns.alpha
|
||||
= f.label :group_ids, t('.groups')
|
||||
%div{'ofn-with-tip' => t('.groups_tip')}
|
||||
%a= t('admin.whats_this')
|
||||
.eight.columns.omega
|
||||
= f.collection_select :group_ids, @groups, :id, :name, {}, class: "select2 fullwidth", multiple: true, placeholder: t('.groups_placeholder')
|
||||
.three.columns.alpha
|
||||
= f.label :group_ids, t('.groups')
|
||||
%div{'ofn-with-tip' => t('.groups_tip')}
|
||||
%a= t('admin.whats_this')
|
||||
.eight.columns.omega
|
||||
= f.collection_select :group_ids, @groups, :id, :name, {}, class: "select2 fullwidth", multiple: true, placeholder: t('.groups_placeholder')
|
||||
|
||||
.row
|
||||
.three.columns.alpha
|
||||
@@ -25,20 +23,19 @@
|
||||
= f.label :is_primary_producer, t('.producer')
|
||||
- if spree_current_user.admin?
|
||||
.row
|
||||
.alpha.eleven.columns
|
||||
.three.columns.alpha
|
||||
= f.label :sells, t('.sells')
|
||||
%div{'ofn-with-tip' => t('.sells_tip')}
|
||||
%a= t('admin.whats_this')
|
||||
.two.columns
|
||||
= f.radio_button :sells, "none", 'ng-model' => 'Enterprise.sells'
|
||||
= f.label :sells, t('.none'), value: "none"
|
||||
.two.columns
|
||||
= f.radio_button :sells, "own", 'ng-model' => 'Enterprise.sells'
|
||||
= f.label :sells, t('.own'), value: "own"
|
||||
.four.columns.omega
|
||||
= f.radio_button :sells, "any", 'ng-model' => 'Enterprise.sells'
|
||||
= f.label :sells, t('.any'), value: "any"
|
||||
.three.columns.alpha
|
||||
= f.label :sells, t('.sells')
|
||||
%div{'ofn-with-tip' => t('.sells_tip')}
|
||||
%a= t('admin.whats_this')
|
||||
.two.columns
|
||||
= f.radio_button :sells, "none", 'ng-model' => 'Enterprise.sells'
|
||||
= f.label :sells, t('.none'), value: "none"
|
||||
.two.columns
|
||||
= f.radio_button :sells, "own", 'ng-model' => 'Enterprise.sells'
|
||||
= f.label :sells, t('.own'), value: "own"
|
||||
.four.columns.omega
|
||||
= f.radio_button :sells, "any", 'ng-model' => 'Enterprise.sells'
|
||||
= f.label :sells, t('.any'), value: "any"
|
||||
.row
|
||||
.three.columns.alpha
|
||||
%label= t('.visible_in_search')
|
||||
@@ -56,10 +53,11 @@
|
||||
= f.label :permalink, t('.permalink')
|
||||
%div{'ofn-with-tip' => t('.permalink_tip', link: main_app.root_url)}
|
||||
%a= t('admin.whats_this')
|
||||
.six.columns
|
||||
.eight.columns
|
||||
= f.text_field :permalink, { 'ng-model' => "Enterprise.permalink", placeholder: "eg. your-shop-name", 'ng-model-options' => "{ updateOn: 'default blur', debounce: {'default': 300, 'blur': 0} }" }
|
||||
.two.columns.omega
|
||||
%img.spinner{ src: image_path("spinning-circles.svg"), width: "30px", ng: { show: "checking" } }
|
||||
%div{ng: {show: "checking", cloak: true}, style: "width: 30px; height: 30px;"}
|
||||
= render partial: "components/spinner"
|
||||
%span{ ng: { class: 'availability.toLowerCase()', hide: "checking" } }
|
||||
{{ availability }}
|
||||
%i{ ng: { class: "{'icon-ok-sign': availability == 'Available', 'icon-remove-sign': availability == 'Unavailable'}" } }
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
%td= link_to t(:edit), edit_admin_shipping_method_path(shipping_method)
|
||||
%br
|
||||
.row
|
||||
.six.columns.alpha
|
||||
.eight.columns
|
||||
%a.button{ href: "#{admin_shipping_methods_path}"}
|
||||
= t('.manage')
|
||||
%i.icon-arrow-right
|
||||
.five.columns.omega.text-right
|
||||
.eight.columns.text-right
|
||||
%a.button{ href: "#{new_admin_shipping_method_path}"}
|
||||
= t('.create_button')
|
||||
%i.icon-plus
|
||||
|
||||
@@ -1,104 +1,95 @@
|
||||
.row
|
||||
.alpha.eleven.columns
|
||||
.three.columns.alpha
|
||||
= f.label "enterprise_preferred_shopfront_message", t('.shopfront_message')
|
||||
.eight.columns.omega
|
||||
%text-angular{'ng-model' => 'Enterprise.preferred_shopfront_message', 'id' => 'enterprise_preferred_shopfront_message', 'name' => 'enterprise[preferred_shopfront_message]', 'class' => 'text-angular textangular-strip', 'ta-paste' => "stripFormatting($html)", "textangular-links-target-blank" => true,
|
||||
'ta-toolbar' => "[['h1','h2','h3','h4','p'],['bold','italics','underline','clear'],['insertLink']]",
|
||||
'placeholder' => t('.shopfront_message_placeholder')}
|
||||
.three.columns.alpha
|
||||
= f.label "enterprise_preferred_shopfront_message", t('.shopfront_message')
|
||||
.eight.columns.omega
|
||||
%text-angular{'ng-model' => 'Enterprise.preferred_shopfront_message', 'id' => 'enterprise_preferred_shopfront_message', 'name' => 'enterprise[preferred_shopfront_message]', 'class' => 'text-angular textangular-strip', 'ta-paste' => "stripFormatting($html)", "textangular-links-target-blank" => true,
|
||||
'ta-toolbar' => "[['h1','h2','h3','h4','p'],['bold','italics','underline','clear'],['insertLink']]",
|
||||
'placeholder' => t('.shopfront_message_placeholder')}
|
||||
.row
|
||||
.alpha.eleven.columns
|
||||
.three.columns.alpha
|
||||
= f.label "enterprise_preferred_shopfront_closed_message", t('.shopfront_closed_message')
|
||||
.eight.columns.omega
|
||||
%text-angular{'ng-model' => 'Enterprise.preferred_shopfront_closed_message', 'id' => 'enterprise_preferred_shopfront_closed_message', 'name' => 'enterprise[preferred_shopfront_closed_message]', 'class' => 'text-angular textangular-strip', 'ta-paste' => "stripFormatting($html)", "textangular-links-target-blank" => true,
|
||||
'ta-toolbar' => "[['h1','h2','h3','h4','p'],['bold','italics','underline','clear'],['insertLink']]",
|
||||
'placeholder' => t('.shopfront_closed_message_placeholder')}
|
||||
.three.columns.alpha
|
||||
= f.label "enterprise_preferred_shopfront_closed_message", t('.shopfront_closed_message')
|
||||
.eight.columns.omega
|
||||
%text-angular{'ng-model' => 'Enterprise.preferred_shopfront_closed_message', 'id' => 'enterprise_preferred_shopfront_closed_message', 'name' => 'enterprise[preferred_shopfront_closed_message]', 'class' => 'text-angular textangular-strip', 'ta-paste' => "stripFormatting($html)", "textangular-links-target-blank" => true,
|
||||
'ta-toolbar' => "[['h1','h2','h3','h4','p'],['bold','italics','underline','clear'],['insertLink']]",
|
||||
'placeholder' => t('.shopfront_closed_message_placeholder')}
|
||||
.row
|
||||
.alpha.eleven.columns
|
||||
.three.columns.alpha
|
||||
= f.label "enterprise_preferred_shopfront_taxon_order", t('.shopfront_category_ordering')
|
||||
%br
|
||||
= t('.shopfront_category_ordering_note')
|
||||
.eight.columns.omega
|
||||
%textarea.fullwidth{ id: 'enterprise_preferred_shopfront_taxon_order', name: 'enterprise[preferred_shopfront_taxon_order]', rows: 6, 'ng-model' => 'Enterprise.preferred_shopfront_taxon_order', 'ofn-taxon-autocomplete' => '', 'multiple-selection' => 'true', placeholder: 'Category' }
|
||||
.three.columns.alpha
|
||||
= f.label "enterprise_preferred_shopfront_taxon_order", t('.shopfront_category_ordering')
|
||||
%br
|
||||
= t('.shopfront_category_ordering_note')
|
||||
.eight.columns.omega
|
||||
%textarea.fullwidth{ id: 'enterprise_preferred_shopfront_taxon_order', name: 'enterprise[preferred_shopfront_taxon_order]', rows: 6, 'ng-model' => 'Enterprise.preferred_shopfront_taxon_order', 'ofn-taxon-autocomplete' => '', 'multiple-selection' => 'true', placeholder: 'Category' }
|
||||
|
||||
.row
|
||||
.alpha.eleven.columns
|
||||
.three.columns.alpha
|
||||
= f.label "enterprise_preferred_shopfront_order_cycle_order", t(:sort_order_cycles_on_shopfront_by)
|
||||
.three.columns
|
||||
= radio_button :enterprise, :preferred_shopfront_order_cycle_order, :orders_open_at, { 'ng-model' => 'Enterprise.preferred_shopfront_order_cycle_order' }
|
||||
= label :enterprise, :preferred_shopfront_order_cycle_order_orders_open_at, t('.open_date')
|
||||
.five.columns.omega
|
||||
= radio_button :enterprise, :preferred_shopfront_order_cycle_order, :orders_close_at, { 'ng-model' => 'Enterprise.preferred_shopfront_order_cycle_order' }
|
||||
= label :enterprise, :preferred_shopfront_order_cycle_order_orders_close_at, t('.close_date')
|
||||
.three.columns.alpha
|
||||
= f.label "enterprise_preferred_shopfront_order_cycle_order", t(:sort_order_cycles_on_shopfront_by)
|
||||
.three.columns
|
||||
= radio_button :enterprise, :preferred_shopfront_order_cycle_order, :orders_open_at, { 'ng-model' => 'Enterprise.preferred_shopfront_order_cycle_order' }
|
||||
= label :enterprise, :preferred_shopfront_order_cycle_order_orders_open_at, t('.open_date')
|
||||
.five.columns.omega
|
||||
= radio_button :enterprise, :preferred_shopfront_order_cycle_order, :orders_close_at, { 'ng-model' => 'Enterprise.preferred_shopfront_order_cycle_order' }
|
||||
= label :enterprise, :preferred_shopfront_order_cycle_order_orders_close_at, t('.close_date')
|
||||
.row
|
||||
.alpha.eleven.columns
|
||||
.three.columns.alpha
|
||||
%label= t '.shopfront_requires_login'
|
||||
%div{'ofn-with-tip' => t('.shopfront_requires_login_tip')}
|
||||
%a= t 'admin.whats_this'
|
||||
.three.columns
|
||||
= f.radio_button :require_login, false, "ng-model" => "Enterprise.require_login", "ng-value" => "false"
|
||||
= f.label :require_login, t('.shopfront_requires_login_false'), value: :false
|
||||
.five.columns.omega
|
||||
= f.radio_button :require_login, true, "ng-model" => "Enterprise.require_login", "ng-value" => "true"
|
||||
= f.label :require_login, t('.shopfront_requires_login_true'), value: :true
|
||||
.three.columns.alpha
|
||||
%label= t '.shopfront_requires_login'
|
||||
%div{'ofn-with-tip' => t('.shopfront_requires_login_tip')}
|
||||
%a= t 'admin.whats_this'
|
||||
.three.columns
|
||||
= f.radio_button :require_login, false, "ng-model" => "Enterprise.require_login", "ng-value" => "false"
|
||||
= f.label :require_login, t('.shopfront_requires_login_false'), value: :false
|
||||
.five.columns.omega
|
||||
= f.radio_button :require_login, true, "ng-model" => "Enterprise.require_login", "ng-value" => "true"
|
||||
= f.label :require_login, t('.shopfront_requires_login_true'), value: :true
|
||||
|
||||
.row{ng: {if: "!Enterprise.require_login"}}
|
||||
.alpha.eleven.columns
|
||||
.three.columns.alpha
|
||||
%label= t '.allow_guest_orders'
|
||||
%div{'ofn-with-tip' => t('.allow_guest_orders_tip')}
|
||||
%a= t 'admin.whats_this'
|
||||
.eight.columns.omega
|
||||
.row
|
||||
.three.columns.alpha
|
||||
= f.radio_button :allow_guest_orders, true, "ng-model" => "Enterprise.allow_guest_orders", "ng-value" => "true"
|
||||
= f.label :allow_guest_orders, t('.allow_guest_orders_true'), value: :true
|
||||
.five.columns.omega
|
||||
= f.radio_button :allow_guest_orders, false, "ng-model" => "Enterprise.allow_guest_orders", "ng-value" => "false"
|
||||
= f.label :allow_guest_orders, t('.allow_guest_orders_false'), value: :false
|
||||
.row.warning{ng: {show: 'Enterprise.allow_guest_orders && Enterprise.allow_order_changes'}}
|
||||
.eight.columns.alpha.omega
|
||||
%i.icon-warning-sign
|
||||
= t '.recommend_require_login'
|
||||
.three.columns.alpha
|
||||
%label= t '.allow_guest_orders'
|
||||
%div{'ofn-with-tip' => t('.allow_guest_orders_tip')}
|
||||
%a= t 'admin.whats_this'
|
||||
.eight.columns.omega
|
||||
.row
|
||||
.three.columns.alpha
|
||||
= f.radio_button :allow_guest_orders, true, "ng-model" => "Enterprise.allow_guest_orders", "ng-value" => "true"
|
||||
= f.label :allow_guest_orders, t('.allow_guest_orders_true'), value: :true
|
||||
.five.columns.omega
|
||||
= f.radio_button :allow_guest_orders, false, "ng-model" => "Enterprise.allow_guest_orders", "ng-value" => "false"
|
||||
= f.label :allow_guest_orders, t('.allow_guest_orders_false'), value: :false
|
||||
.row.warning{ng: {show: 'Enterprise.allow_guest_orders && Enterprise.allow_order_changes'}}
|
||||
.eight.columns.alpha.omega
|
||||
%i.icon-warning-sign
|
||||
= t '.recommend_require_login'
|
||||
.row
|
||||
.alpha.eleven.columns
|
||||
.three.columns.alpha
|
||||
%label= t '.allow_order_changes'
|
||||
%div{'ofn-with-tip' => t('.allow_order_changes_tip')}
|
||||
%a= t 'admin.whats_this'
|
||||
.three.columns
|
||||
= f.radio_button :allow_order_changes, false, "ng-model" => "Enterprise.allow_order_changes", "ng-value" => "false"
|
||||
= f.label :allow_order_changes, t('.allow_order_changes_false'), value: :false
|
||||
.five.columns.omega
|
||||
= f.radio_button :allow_order_changes, true, "ng-model" => "Enterprise.allow_order_changes", "ng-value" => "true"
|
||||
= f.label :allow_order_changes, t('.allow_order_changes_true'), value: :true
|
||||
.three.columns.alpha
|
||||
%label= t '.allow_order_changes'
|
||||
%div{'ofn-with-tip' => t('.allow_order_changes_tip')}
|
||||
%a= t 'admin.whats_this'
|
||||
.three.columns
|
||||
= f.radio_button :allow_order_changes, false, "ng-model" => "Enterprise.allow_order_changes", "ng-value" => "false"
|
||||
= f.label :allow_order_changes, t('.allow_order_changes_false'), value: :false
|
||||
.five.columns.omega
|
||||
= f.radio_button :allow_order_changes, true, "ng-model" => "Enterprise.allow_order_changes", "ng-value" => "true"
|
||||
= f.label :allow_order_changes, t('.allow_order_changes_true'), value: :true
|
||||
|
||||
.row
|
||||
.alpha.eleven.columns
|
||||
.three.columns.alpha
|
||||
%label= t '.enable_subscriptions'
|
||||
%div{'ofn-with-tip' => t('.enable_subscriptions_tip')}
|
||||
%a= t 'admin.whats_this'
|
||||
.three.columns
|
||||
= f.radio_button :enable_subscriptions, true
|
||||
= f.label :enable_subscriptions, t('.enable_subscriptions_true'), value: :true
|
||||
.five.columns.omega
|
||||
= f.radio_button :enable_subscriptions, false
|
||||
= f.label :enable_subscriptions, t('.enable_subscriptions_false'), value: :false
|
||||
.three.columns.alpha
|
||||
%label= t '.enable_subscriptions'
|
||||
%div{'ofn-with-tip' => t('.enable_subscriptions_tip')}
|
||||
%a= t 'admin.whats_this'
|
||||
.three.columns
|
||||
= f.radio_button :enable_subscriptions, true
|
||||
= f.label :enable_subscriptions, t('.enable_subscriptions_true'), value: :true
|
||||
.five.columns.omega
|
||||
= f.radio_button :enable_subscriptions, false
|
||||
= f.label :enable_subscriptions, t('.enable_subscriptions_false'), value: :false
|
||||
|
||||
.row
|
||||
.alpha.eleven.columns
|
||||
.three.columns.alpha
|
||||
%label= t '.customer_names_in_reports'
|
||||
%div{'ofn-with-tip' => t('.customer_names_tip')}
|
||||
%a= t 'admin.whats_this'
|
||||
.three.columns
|
||||
= radio_button :enterprise, :preferred_show_customer_names_to_suppliers, true
|
||||
= label :enterprise_preferred_show_customer_names_to_suppliers, t('.customer_names_true'), value: :true
|
||||
.five.columns.omega
|
||||
= radio_button :enterprise, :preferred_show_customer_names_to_suppliers, false
|
||||
= label :enterprise_preferred_show_customer_names_to_suppliers, t('.customer_names_false'), value: :false
|
||||
.three.columns.alpha
|
||||
%label= t '.customer_names_in_reports'
|
||||
%div{'ofn-with-tip' => t('.customer_names_tip')}
|
||||
%a= t 'admin.whats_this'
|
||||
.three.columns
|
||||
= radio_button :enterprise, :preferred_show_customer_names_to_suppliers, true
|
||||
= label :enterprise_preferred_show_customer_names_to_suppliers, t('.customer_names_true'), value: :true
|
||||
.five.columns.omega
|
||||
= radio_button :enterprise, :preferred_show_customer_names_to_suppliers, false
|
||||
= label :enterprise_preferred_show_customer_names_to_suppliers, t('.customer_names_false'), value: :false
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
= "admin.enterprises"
|
||||
|
||||
- content_for :page_actions do
|
||||
= render 'admin/shared/user_guide_link'
|
||||
%li#user_guide_link
|
||||
= render 'admin/shared/user_guide_link'
|
||||
|
||||
%li#new_product_link
|
||||
- button_href = spree_current_user.can_own_more_enterprises? ? main_app.new_admin_enterprise_path : '#'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
%div.sixteen.columns.alpha.omega#loading{ ng: { cloak: true, if: 'RequestMonitor.loading' } }
|
||||
%img.spinner{ src: image_path("spinning-circles.svg") }
|
||||
= render partial: "components/spinner"
|
||||
%h1{ ng: { hide: 'orderCycles.length > 0' } }
|
||||
=t('.loading_order_cycles')
|
||||
%h1{ ng: { show: 'orderCycles.length > 0' } }
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
.alpha.two.columns
|
||||
= f.label :name, t('.name')
|
||||
%span.required *
|
||||
.six.columns.omega
|
||||
.six.columns.omega.fullwidth_inputs
|
||||
- if viewing_as_coordinator_of?(@order_cycle)
|
||||
= f.text_field :name, 'ng-model' => 'order_cycle.name', 'required' => true, 'ng-disabled' => '!loaded()'
|
||||
- else
|
||||
{{ order_cycle.name }}
|
||||
.two.columns
|
||||
= f.label :orders_open_at, t('.orders_open')
|
||||
.omega.six.columns
|
||||
.omega.six.columns.fullwidth_inputs
|
||||
- if viewing_as_coordinator_of?(@order_cycle)
|
||||
= f.text_field :orders_open_at, 'datetimepicker' => 'order_cycle.orders_open_at', 'ng-model' => 'order_cycle.orders_open_at', 'ng-disabled' => '!loaded()', 'change-warning' => 'order_cycle'
|
||||
- else
|
||||
@@ -18,11 +18,11 @@
|
||||
.row
|
||||
.alpha.two.columns
|
||||
= f.label :coordinator, t('.coordinator')
|
||||
.six.columns.omega
|
||||
.six.columns.omega.fullwidth_inputs
|
||||
= @order_cycle.coordinator.name
|
||||
.two.columns
|
||||
= f.label :orders_close, t('.orders_close')
|
||||
.six.columns.omega
|
||||
.six.columns.omega.fullwidth_inputs
|
||||
- if viewing_as_coordinator_of?(@order_cycle)
|
||||
= f.text_field :orders_close_at, 'datetimepicker' => 'order_cycle.orders_close_at', 'ng-model' => 'order_cycle.orders_close_at', 'ng-disabled' => '!loaded()', 'change-warning' => 'order_cycle'
|
||||
- else
|
||||
@@ -33,7 +33,7 @@
|
||||
.row
|
||||
.two.columns.alpha
|
||||
= f.label :schedule_ids, t('admin.order_cycles.index.schedules')
|
||||
.twelve.columns
|
||||
.six.columns
|
||||
- if viewing_as_coordinator_of?(@order_cycle)
|
||||
%input.fullwidth.ofn-select2#schedule_ids{ name: 'order_cycle[schedule_ids]',
|
||||
data: 'schedules',
|
||||
@@ -43,5 +43,3 @@
|
||||
ng: { model: 'order_cycle.schedule_ids' } }
|
||||
- else
|
||||
%schedule-list{ 'order-cycle' => 'order_cycle' }
|
||||
.two.columns.omega
|
||||
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
.alpha.two.columns
|
||||
= label_tag t('.ready_for')
|
||||
%span.required *
|
||||
.six.columns
|
||||
= text_field_tag 'order_cycle_outgoing_exchange_0_pickup_time', '', 'id' => 'order_cycle_outgoing_exchange_0_pickup_time', 'required' => 'required', 'placeholder' => t('.ready_for_placeholder'), 'ng-model' => 'outgoing_exchange.pickup_time', 'size' => 30, 'maxlength' => 35
|
||||
%span.icon-question-sign{'ofn-with-tip' => t('admin.order_cycles.exchange_form.pickup_time_tip')}
|
||||
.six.columns.fullwidth_inputs
|
||||
= text_field_tag 'order_cycle_outgoing_exchange_0_pickup_time', '', 'id' => 'order_cycle_outgoing_exchange_0_pickup_time', 'required' => 'required', 'placeholder' => t('.ready_for_placeholder'), 'ng-model' => 'outgoing_exchange.pickup_time', 'maxlength' => 35
|
||||
.two.columns
|
||||
= label_tag t('.customer_instructions')
|
||||
.six.columns.omega
|
||||
= text_field_tag 'order_cycle_outgoing_exchange_0_pickup_instructions', '', 'id' => 'order_cycle_outgoing_exchange_0_pickup_instructions', 'placeholder' => t('.customer_instructions_placeholder'), 'ng-model' => 'outgoing_exchange.pickup_instructions', 'size' => 30
|
||||
%span.icon-question-sign{'ofn-with-tip' => t('admin.order_cycles.exchange_form.pickup_instructions_tip')}
|
||||
.six.columns.omega.fullwidth_inputs
|
||||
= text_field_tag 'order_cycle_outgoing_exchange_0_pickup_instructions', '', 'id' => 'order_cycle_outgoing_exchange_0_pickup_instructions', 'placeholder' => t('.customer_instructions_placeholder'), 'ng-model' => 'outgoing_exchange.pickup_instructions', 'size' => 30
|
||||
|
||||
= label_tag t('.products')
|
||||
%table.exchanges
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user