mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-14 18:56:49 +00:00
Compare commits
239 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e6a1021d6e | ||
|
|
e82aa0c89a | ||
|
|
8be05e94bd | ||
|
|
7317347fd6 | ||
|
|
c5c542069f | ||
|
|
dc9e3aa1a0 | ||
|
|
a48b57f7a7 | ||
|
|
f501d48caa | ||
|
|
2429b186ce | ||
|
|
7df2759475 | ||
|
|
681cb34c48 | ||
|
|
94b903179e | ||
|
|
59070712d9 | ||
|
|
76aebf329e | ||
|
|
b2b5606f2e | ||
|
|
f890c4a31d | ||
|
|
b087f8da19 | ||
|
|
e3c1159c17 | ||
|
|
14054f0e70 | ||
|
|
d525ddfe14 | ||
|
|
df0b997258 | ||
|
|
ffbb0d26a4 | ||
|
|
3da14233bf | ||
|
|
940c067b60 | ||
|
|
6e8fe080cb | ||
|
|
8867ec977c | ||
|
|
4931edc67c | ||
|
|
51ed9a6b78 | ||
|
|
e96428e7e2 | ||
|
|
b629a4f912 | ||
|
|
967380c542 | ||
|
|
ff0aa377a1 | ||
|
|
da683e3ecf | ||
|
|
aa46a4b5da | ||
|
|
61dad61ef7 | ||
|
|
60e241b2c8 | ||
|
|
d8165aeec1 | ||
|
|
c7bcd61755 | ||
|
|
9c0c324835 | ||
|
|
874cb78809 | ||
|
|
4499bc7313 | ||
|
|
4fe24da3ec | ||
|
|
d80a44ade0 | ||
|
|
42d90465b1 | ||
|
|
457dfdd18a | ||
|
|
8f896a806a | ||
|
|
71b1c5a3b3 | ||
|
|
8256a20aea | ||
|
|
07e17d7931 | ||
|
|
e177ba5e29 | ||
|
|
d3f48bf684 | ||
|
|
63a6ceede3 | ||
|
|
185c246a83 | ||
|
|
83361255aa | ||
|
|
b4759ff869 | ||
|
|
5bc0eca493 | ||
|
|
f6eb05a6f1 | ||
|
|
cd940bd140 | ||
|
|
09f0035bbd | ||
|
|
2cb6124b7a | ||
|
|
653b71dbd4 | ||
|
|
b36d0bc4f3 | ||
|
|
b2cf414fb8 | ||
|
|
5958c2f68c | ||
|
|
13f0a46bc2 | ||
|
|
b9f7a98c46 | ||
|
|
a65bd8edac | ||
|
|
ea053552b9 | ||
|
|
52fb3c92f0 | ||
|
|
5e49e03477 | ||
|
|
b35d579f64 | ||
|
|
3198bbd3cb | ||
|
|
bf81b5a305 | ||
|
|
d87d5d3537 | ||
|
|
e0ea25b7a3 | ||
|
|
8f19ad0646 | ||
|
|
e89eb8f76c | ||
|
|
0b053c18af | ||
|
|
d13bd86e4c | ||
|
|
c56962b949 | ||
|
|
3df5a0644f | ||
|
|
6bb37a3942 | ||
|
|
a029a86f0d | ||
|
|
c9758b8b0b | ||
|
|
bf07da6267 | ||
|
|
bb9ab57699 | ||
|
|
7e274868fa | ||
|
|
7cb49ac9a8 | ||
|
|
9efee1b0be | ||
|
|
defb6e4fa4 | ||
|
|
96cd40e446 | ||
|
|
37bfdf69a9 | ||
|
|
a441979649 | ||
|
|
62339de603 | ||
|
|
9b2cb1c3ef | ||
|
|
58c0b1e0fd | ||
|
|
4984cc9758 | ||
|
|
2a71af7c6b | ||
|
|
819a445547 | ||
|
|
d57f20a542 | ||
|
|
28651bbecf | ||
|
|
06b41a8236 | ||
|
|
2fa8cd54fd | ||
|
|
043e175fa1 | ||
|
|
a1b4c7fdf2 | ||
|
|
6e3cfe9c54 | ||
|
|
8583ac5573 | ||
|
|
300e12371a | ||
|
|
8f59b048f3 | ||
|
|
8290acfd91 | ||
|
|
a8bfedd847 | ||
|
|
ef0038a661 | ||
|
|
6f33ae586e | ||
|
|
4e635e114c | ||
|
|
5d48da72c7 | ||
|
|
9d07295480 | ||
|
|
f435039061 | ||
|
|
da1569abda | ||
|
|
7ce9a3f988 | ||
|
|
7a0b036edd | ||
|
|
d81ed36eef | ||
|
|
5b3e350204 | ||
|
|
53de04121c | ||
|
|
23c86a1937 | ||
|
|
fb88cfedcf | ||
|
|
94d1d5f3ae | ||
|
|
f9aac02e13 | ||
|
|
274cdefa26 | ||
|
|
9264badaaf | ||
|
|
152eb11913 | ||
|
|
0421d23e7b | ||
|
|
5ce51a4abb | ||
|
|
1c7ce9997a | ||
|
|
489665f3f9 | ||
|
|
cad79d74c8 | ||
|
|
f9e29c5aa7 | ||
|
|
ad9d9afd6a | ||
|
|
41d67d8b2e | ||
|
|
5568fd5826 | ||
|
|
f6277416ce | ||
|
|
4de4cc642d | ||
|
|
cd22361d13 | ||
|
|
1ddda92f4d | ||
|
|
4048957e2e | ||
|
|
2abbfad18c | ||
|
|
292199441a | ||
|
|
f56fa0b7a5 | ||
|
|
a432bbf789 | ||
|
|
6d9250c014 | ||
|
|
6d05de742e | ||
|
|
aa00756f9c | ||
|
|
ee65b4ba27 | ||
|
|
e2a865476d | ||
|
|
9e7e63cc94 | ||
|
|
4dd1a52f8e | ||
|
|
f6f6d9b46f | ||
|
|
204e3979d9 | ||
|
|
ad8c41e0ad | ||
|
|
acb1c41461 | ||
|
|
859d34c235 | ||
|
|
8d74c69402 | ||
|
|
4ac6664502 | ||
|
|
53a8fec181 | ||
|
|
313e6e2b45 | ||
|
|
6819042489 | ||
|
|
e1fb13b491 | ||
|
|
aa9054659e | ||
|
|
172a12d7d9 | ||
|
|
e561bcc895 | ||
|
|
9390fd6ccb | ||
|
|
b227c78aeb | ||
|
|
a44d0f7af6 | ||
|
|
41a7e26fcd | ||
|
|
5cd40cb19f | ||
|
|
907afe3131 | ||
|
|
261269bd57 | ||
|
|
d0c07b931a | ||
|
|
b6adef38e5 | ||
|
|
0ca4d0842a | ||
|
|
e5395709cc | ||
|
|
2515b1ae2c | ||
|
|
cdd09e8f97 | ||
|
|
2f1fdc5852 | ||
|
|
07b819ab4b | ||
|
|
50fd3656ef | ||
|
|
4243ff293f | ||
|
|
c79f2326fc | ||
|
|
ac69bef459 | ||
|
|
debbf9b361 | ||
|
|
1f470830c8 | ||
|
|
a00e964eb6 | ||
|
|
8e5cfdeb97 | ||
|
|
eb420d9eed | ||
|
|
d1ef0e0a0b | ||
|
|
0efcf1536f | ||
|
|
f8146fb946 | ||
|
|
91789494b0 | ||
|
|
2eda8789d1 | ||
|
|
67a00173f8 | ||
|
|
5f8fc64b31 | ||
|
|
97ae4def98 | ||
|
|
91501f05f2 | ||
|
|
93601ca556 | ||
|
|
2f5efc86ee | ||
|
|
102df28e97 | ||
|
|
0b91991919 | ||
|
|
9a9538dace | ||
|
|
23bb72faa6 | ||
|
|
7c223a43fc | ||
|
|
d46fad3a02 | ||
|
|
c75a864ff2 | ||
|
|
dee34d1f26 | ||
|
|
13bf7497a9 | ||
|
|
a860b5ea42 | ||
|
|
09b7aa134b | ||
|
|
49a60374e6 | ||
|
|
1b66a72c7f | ||
|
|
798194c03e | ||
|
|
b21a969502 | ||
|
|
d746ae3d9e | ||
|
|
621e2a3132 | ||
|
|
142bab8c35 | ||
|
|
abaa66cc14 | ||
|
|
6f17b80bb8 | ||
|
|
43e64f3555 | ||
|
|
73e1530a30 | ||
|
|
b09a9c5b8b | ||
|
|
00ae3a25f7 | ||
|
|
14358256ed | ||
|
|
422958ed6f | ||
|
|
51f39ee89d | ||
|
|
ef7c7a3e73 | ||
|
|
3c23952fd6 | ||
|
|
bda47d97ee | ||
|
|
d43e9b5716 | ||
|
|
429c88c000 | ||
|
|
79abc191ff | ||
|
|
3a722bc697 | ||
|
|
7e195c3856 |
3
.github/ISSUE_TEMPLATE/release.md
vendored
3
.github/ISSUE_TEMPLATE/release.md
vendored
@@ -9,10 +9,11 @@ assignees: ''
|
||||
|
||||
Steps:
|
||||
|
||||
- [ ] Include translations
|
||||
- [ ] Include translations: `tx pull --force`
|
||||
- [ ] [Draft new release]
|
||||
- [ ] Notify #instance-managers of user-facing changes.
|
||||
- [ ] Test: https://semaphoreci.com/openfoodfoundation/openfoodnetwork-2/branches/master <!-- replace the URL -->
|
||||
- [ ] Update translations if necessary
|
||||
- [ ] Publish and notify #global-community
|
||||
- [ ] Deploy and notify #instance-managers
|
||||
- [ ] Nudge next release manager
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,5 +1,6 @@
|
||||
.bundle
|
||||
.rbenv-version
|
||||
.python-version
|
||||
.byebug_history
|
||||
.swp
|
||||
*.swo
|
||||
|
||||
@@ -330,6 +330,13 @@ Layout/LineLength:
|
||||
- spec/requests/api/orders_spec.rb
|
||||
- spec/swagger_helper.rb
|
||||
- spec/views/spree/admin/payment_methods/index.html.haml_spec.rb
|
||||
- app/models/spree/image.rb
|
||||
- app/models/spree/payment_method.rb
|
||||
- spec/factories/line_item_factory.rb
|
||||
- spec/factories/shipment_factory.rb
|
||||
- spec/factories/stock_location_factory.rb
|
||||
- spec/factories/user_factory.rb
|
||||
- spec/lib/spree/core/calculated_adjustments_spec.rb
|
||||
|
||||
Metrics/AbcSize:
|
||||
Max: 15
|
||||
@@ -459,6 +466,13 @@ Metrics/AbcSize:
|
||||
- app/models/spree/payment/processing.rb
|
||||
- app/models/spree/payment.rb
|
||||
- engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_report.rb
|
||||
- app/models/spree/zone.rb
|
||||
- lib/spree/core/calculated_adjustments.rb
|
||||
- lib/spree/core/delegate_belongs_to.rb
|
||||
- lib/spree/core/permalinks.rb
|
||||
- lib/spree/core/s3_support.rb
|
||||
- lib/spree/money.rb
|
||||
- spec/support/i18n_translations_checker.rb
|
||||
|
||||
Metrics/BlockLength:
|
||||
Max: 25
|
||||
@@ -501,6 +515,9 @@ Metrics/BlockLength:
|
||||
- app/models/spree/payment/processing.rb
|
||||
- spec/requests/api/orders_spec.rb
|
||||
- spec/swagger_helper.rb
|
||||
- spec/factories/address_factory.rb
|
||||
- spec/factories/payment_method_factory.rb
|
||||
- spec/factories/shipment_factory.rb
|
||||
|
||||
Metrics/CyclomaticComplexity:
|
||||
Max: 6
|
||||
@@ -535,6 +552,9 @@ Metrics/CyclomaticComplexity:
|
||||
- app/models/spree/order/checkout.rb
|
||||
- app/models/spree/payment.rb
|
||||
- engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_report.rb
|
||||
- app/models/spree/payment_method.rb
|
||||
- app/models/spree/zone.rb
|
||||
- lib/spree/core/calculated_adjustments.rb
|
||||
|
||||
Metrics/PerceivedComplexity:
|
||||
Max: 7
|
||||
@@ -563,6 +583,8 @@ Metrics/PerceivedComplexity:
|
||||
- spec/models/product_importer_spec.rb
|
||||
- app/models/spree/order/checkout.rb
|
||||
- engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_report.rb
|
||||
- app/models/spree/zone.rb
|
||||
- lib/spree/core/calculated_adjustments.rb
|
||||
|
||||
Metrics/MethodLength:
|
||||
Max: 10
|
||||
@@ -675,6 +697,15 @@ Metrics/MethodLength:
|
||||
- engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_allocation_report.rb
|
||||
- engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_report.rb
|
||||
- engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_supplier_report.rb
|
||||
- app/models/spree/credit_card.rb
|
||||
- app/models/spree/payment_method.rb
|
||||
- app/models/spree/zone.rb
|
||||
- lib/spree/core/calculated_adjustments.rb
|
||||
- lib/spree/core/delegate_belongs_to.rb
|
||||
- lib/spree/core/permalinks.rb
|
||||
- lib/spree/core/s3_support.rb
|
||||
- lib/spree/responder.rb
|
||||
- spec/support/i18n_translations_checker.rb
|
||||
|
||||
Metrics/ClassLength:
|
||||
Max: 100
|
||||
@@ -719,6 +750,8 @@ Metrics/ClassLength:
|
||||
- lib/open_food_network/xero_invoices_report.rb
|
||||
- app/models/spree/payment.rb
|
||||
- engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_report.rb
|
||||
- app/models/spree/credit_card.rb
|
||||
- app/models/spree/zone.rb
|
||||
|
||||
Metrics/ModuleLength:
|
||||
Max: 100
|
||||
@@ -764,6 +797,8 @@ Metrics/ModuleLength:
|
||||
- spec/support/request/web_helper.rb
|
||||
- app/models/spree/order/checkout.rb
|
||||
- app/models/spree/payment/processing.rb
|
||||
- spec/lib/open_food_network/packing_report_spec.rb
|
||||
- spec/models/spree/credit_card_spec.rb
|
||||
|
||||
Metrics/ParameterLists:
|
||||
Max: 5
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# This configuration was generated by
|
||||
# `rubocop --auto-gen-config --exclude-limit 1400`
|
||||
# on 2020-08-13 16:05:53 +1000 using RuboCop version 0.81.0.
|
||||
# on 2020-09-10 16:12:05 +1000 using RuboCop version 0.81.0.
|
||||
# The point is for the user to remove these configuration records
|
||||
# one by one as the offenses are removed from the code base.
|
||||
# Note that changes in the inspected code, or installation of new
|
||||
@@ -28,13 +28,14 @@ Layout/EmptyLines:
|
||||
Exclude:
|
||||
- 'spec/models/spree/payment_spec.rb'
|
||||
|
||||
# Offense count: 3
|
||||
# Offense count: 4
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle.
|
||||
# SupportedStyles: empty_lines, no_empty_lines
|
||||
Layout/EmptyLinesAroundBlockBody:
|
||||
Exclude:
|
||||
- 'spec/models/spree/payment_spec.rb'
|
||||
- 'spec/models/spree/zone_spec.rb'
|
||||
|
||||
# Offense count: 3
|
||||
# Cop supports --auto-correct.
|
||||
@@ -61,7 +62,7 @@ Layout/FirstHashElementIndentation:
|
||||
- 'spec/models/spree/payment_spec.rb'
|
||||
- 'spec/swagger_helper.rb'
|
||||
|
||||
# Offense count: 5
|
||||
# Offense count: 8
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle.
|
||||
# SupportedHashRocketStyles: key, separator, table
|
||||
@@ -69,6 +70,7 @@ Layout/FirstHashElementIndentation:
|
||||
# SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
|
||||
Layout/HashAlignment:
|
||||
Exclude:
|
||||
- 'spec/lib/open_food_network/packing_report_spec.rb'
|
||||
- 'spec/models/spree/payment_spec.rb'
|
||||
|
||||
# Offense count: 1
|
||||
@@ -79,13 +81,6 @@ Layout/IndentationConsistency:
|
||||
Exclude:
|
||||
- 'spec/models/spree/order/checkout_spec.rb'
|
||||
|
||||
# Offense count: 26
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
||||
# URISchemes: http, https
|
||||
Layout/LineLength:
|
||||
Max: 409
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle.
|
||||
@@ -123,13 +118,22 @@ Layout/SpaceInsideHashLiteralBraces:
|
||||
- 'spec/services/checkout/form_data_adapter_spec.rb'
|
||||
- 'spec/services/user_locale_setter_spec.rb'
|
||||
|
||||
# Offense count: 2
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle.
|
||||
# SupportedStyles: final_newline, final_blank_line
|
||||
Layout/TrailingEmptyLines:
|
||||
Exclude:
|
||||
- 'spec/factories.rb'
|
||||
- 'spec/factories/address_factory.rb'
|
||||
|
||||
# Offense count: 6
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: AllowInHeredoc.
|
||||
Layout/TrailingWhitespace:
|
||||
Exclude:
|
||||
- 'spec/controllers/base_controller2_spec.rb'
|
||||
- 'spec/features/consumer/shopping/shopping_spec.rb'
|
||||
- 'spec/lib/open_food_network/orders_and_fulfillments_report/customer_totals_report_spec.rb'
|
||||
- 'spec/requests/api/orders_spec.rb'
|
||||
|
||||
# Offense count: 2
|
||||
@@ -145,6 +149,13 @@ Lint/IneffectiveAccessModifier:
|
||||
- 'app/services/mail_configuration.rb'
|
||||
- 'lib/open_food_network/feature_toggle.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments.
|
||||
Lint/UnusedBlockArgument:
|
||||
Exclude:
|
||||
- 'spec/factories/stock_location_factory.rb'
|
||||
|
||||
# Offense count: 4
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods.
|
||||
@@ -160,48 +171,6 @@ Lint/UselessAccessModifier:
|
||||
- 'app/services/mail_configuration.rb'
|
||||
- 'lib/open_food_network/feature_toggle.rb'
|
||||
|
||||
# Offense count: 1
|
||||
Lint/UselessAssignment:
|
||||
Exclude:
|
||||
- 'spec/**/*'
|
||||
- 'lib/spree/core/controller_helpers/common.rb'
|
||||
|
||||
# Offense count: 19
|
||||
# Configuration parameters: IgnoredMethods.
|
||||
Metrics/AbcSize:
|
||||
Max: 126
|
||||
|
||||
# Offense count: 7
|
||||
# Configuration parameters: CountComments, ExcludedMethods.
|
||||
# ExcludedMethods: refine
|
||||
Metrics/BlockLength:
|
||||
Max: 102
|
||||
|
||||
# Offense count: 2
|
||||
# Configuration parameters: CountComments.
|
||||
Metrics/ClassLength:
|
||||
Max: 231
|
||||
|
||||
# Offense count: 3
|
||||
# Configuration parameters: IgnoredMethods.
|
||||
Metrics/CyclomaticComplexity:
|
||||
Max: 23
|
||||
|
||||
# Offense count: 19
|
||||
# Configuration parameters: CountComments, ExcludedMethods.
|
||||
Metrics/MethodLength:
|
||||
Max: 140
|
||||
|
||||
# Offense count: 2
|
||||
# Configuration parameters: CountComments.
|
||||
Metrics/ModuleLength:
|
||||
Max: 208
|
||||
|
||||
# Offense count: 2
|
||||
# Configuration parameters: IgnoredMethods.
|
||||
Metrics/PerceivedComplexity:
|
||||
Max: 24
|
||||
|
||||
# Offense count: 9
|
||||
Naming/AccessorMethodName:
|
||||
Exclude:
|
||||
@@ -227,7 +196,7 @@ Naming/MemoizedInstanceVariableName:
|
||||
- 'app/mailers/producer_mailer.rb'
|
||||
- 'lib/open_food_network/address_finder.rb'
|
||||
|
||||
# Offense count: 19
|
||||
# Offense count: 20
|
||||
# Configuration parameters: NamePrefix, ForbiddenPrefixes, AllowedMethods, MethodDefinitionMacros.
|
||||
# NamePrefix: is_, has_, have_
|
||||
# ForbiddenPrefixes: is_, has_, have_
|
||||
@@ -241,9 +210,10 @@ Naming/PredicateName:
|
||||
- 'app/models/order_cycle.rb'
|
||||
- 'app/models/spree/ability_decorator.rb'
|
||||
- 'app/models/spree/adjustment_decorator.rb'
|
||||
- 'app/models/spree/credit_card.rb'
|
||||
- 'app/models/spree/line_item_decorator.rb'
|
||||
- 'app/models/spree/order_decorator.rb'
|
||||
- 'app/models/spree/payment_method_decorator.rb'
|
||||
- 'app/models/spree/payment_method.rb'
|
||||
- 'app/models/spree/preferences/file_configuration.rb'
|
||||
- 'app/models/spree/shipping_method_decorator.rb'
|
||||
- 'lib/open_food_network/customers_report.rb'
|
||||
@@ -252,6 +222,13 @@ Naming/PredicateName:
|
||||
- 'lib/open_food_network/packing_report.rb'
|
||||
- 'lib/tasks/data.rake'
|
||||
|
||||
# Offense count: 2
|
||||
# Configuration parameters: EnforcedStyle.
|
||||
# SupportedStyles: snake_case, normalcase, non_integer
|
||||
Naming/VariableNumber:
|
||||
Exclude:
|
||||
- 'spec/factories/stock_location_factory.rb'
|
||||
|
||||
# Offense count: 7
|
||||
# Cop supports --auto-correct.
|
||||
Rails/ActiveRecordAliases:
|
||||
@@ -261,12 +238,13 @@ Rails/ActiveRecordAliases:
|
||||
- 'spec/features/consumer/shopping/orders_spec.rb'
|
||||
- 'spec/requests/api/orders_spec.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Offense count: 3
|
||||
# Configuration parameters: EnforcedStyle.
|
||||
# SupportedStyles: strict, flexible
|
||||
Rails/Date:
|
||||
Exclude:
|
||||
- 'app/models/order_cycle.rb'
|
||||
- 'app/models/spree/credit_card.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
@@ -281,7 +259,7 @@ Rails/Delegate:
|
||||
# Whitelist: find_by_sql
|
||||
Rails/DynamicFindBy:
|
||||
Exclude:
|
||||
- 'app/controllers/spree/admin/orders/customer_details_controller.rb'
|
||||
- 'spec/factories/state_factory.rb'
|
||||
|
||||
# Offense count: 16
|
||||
# Configuration parameters: EnforcedStyle.
|
||||
@@ -323,7 +301,7 @@ Rails/FindEach:
|
||||
- 'app/models/spree/order_decorator.rb'
|
||||
- 'app/models/spree/shipment.rb'
|
||||
|
||||
# Offense count: 5
|
||||
# Offense count: 6
|
||||
# Configuration parameters: Include.
|
||||
# Include: app/models/**/*.rb
|
||||
Rails/HasAndBelongsToMany:
|
||||
@@ -332,8 +310,9 @@ Rails/HasAndBelongsToMany:
|
||||
- 'app/models/enterprise_group.rb'
|
||||
- 'app/models/spree/concerns/payment_method_distributors.rb'
|
||||
- 'app/models/spree/line_item_decorator.rb'
|
||||
- 'app/models/spree/zone.rb'
|
||||
|
||||
# Offense count: 26
|
||||
# Offense count: 27
|
||||
# Configuration parameters: Include.
|
||||
# Include: app/models/**/*.rb
|
||||
Rails/HasManyOrHasOneDependent:
|
||||
@@ -342,8 +321,9 @@ Rails/HasManyOrHasOneDependent:
|
||||
- 'app/models/enterprise.rb'
|
||||
- 'app/models/order_cycle.rb'
|
||||
- 'app/models/spree/adjustment_decorator.rb'
|
||||
- 'app/models/spree/credit_card.rb'
|
||||
- 'app/models/spree/order_decorator.rb'
|
||||
- 'app/models/spree/payment_method_decorator.rb'
|
||||
- 'app/models/spree/payment_method.rb'
|
||||
- 'app/models/spree/property.rb'
|
||||
- 'app/models/spree/shipment.rb'
|
||||
- 'app/models/spree/shipping_method_decorator.rb'
|
||||
@@ -392,7 +372,7 @@ Rails/LexicallyScopedActionFilter:
|
||||
- 'app/controllers/spree/users_controller.rb'
|
||||
- 'app/controllers/user_passwords_controller.rb'
|
||||
|
||||
# Offense count: 12
|
||||
# Offense count: 13
|
||||
Rails/OutputSafety:
|
||||
Exclude:
|
||||
- 'app/controllers/spree/admin/reports_controller.rb'
|
||||
@@ -403,6 +383,7 @@ Rails/OutputSafety:
|
||||
- 'app/helpers/spree/admin/zones_helper.rb'
|
||||
- 'app/helpers/spree/reports_helper.rb'
|
||||
- 'app/serializers/api/product_serializer.rb'
|
||||
- 'lib/spree/money.rb'
|
||||
- 'lib/spree/money_decorator.rb'
|
||||
- 'spec/features/admin/order_print_ticket_spec.rb'
|
||||
|
||||
@@ -422,7 +403,7 @@ Rails/ReflectionClassName:
|
||||
- 'app/models/enterprise_role.rb'
|
||||
- 'app/models/subscription.rb'
|
||||
|
||||
# Offense count: 233
|
||||
# Offense count: 241
|
||||
# Configuration parameters: Blacklist, Whitelist.
|
||||
# Blacklist: decrement!, decrement_counter, increment!, increment_counter, toggle!, touch, update_all, update_attribute, update_column, update_columns, update_counters
|
||||
Rails/SkipsModelValidations:
|
||||
@@ -439,17 +420,19 @@ Rails/SkipsModelValidations:
|
||||
- 'app/models/product_import/inventory_reset_strategy.rb'
|
||||
- 'app/models/proxy_order.rb'
|
||||
- 'app/models/spree/address_decorator.rb'
|
||||
- 'app/models/spree/credit_card_decorator.rb'
|
||||
- 'app/models/spree/credit_card.rb'
|
||||
- 'app/models/spree/order_decorator.rb'
|
||||
- 'app/models/spree/payment.rb'
|
||||
- 'app/models/spree/shipment.rb'
|
||||
- 'app/models/spree/shipping_method_decorator.rb'
|
||||
- 'app/models/spree/zone.rb'
|
||||
- 'app/models/subscription.rb'
|
||||
- 'app/models/variant_override.rb'
|
||||
- 'app/services/order_factory.rb'
|
||||
- 'engines/order_management/spec/performance/order_management/subscriptions/proxy_order_syncer_spec.rb'
|
||||
- 'engines/order_management/spec/services/order_management/reports/enterprise_fee_summary/report_service_spec.rb'
|
||||
- 'engines/order_management/spec/services/order_management/subscriptions/stripe_payment_setup_spec.rb'
|
||||
- 'lib/spree/core/calculated_adjustments.rb'
|
||||
- 'lib/tasks/data/anonymize_data.rake'
|
||||
- 'lib/tasks/sample_data/product_factory.rb'
|
||||
- 'lib/tasks/users.rake'
|
||||
@@ -494,6 +477,7 @@ Rails/SkipsModelValidations:
|
||||
- 'spec/models/enterprise_relationship_spec.rb'
|
||||
- 'spec/models/exchange_spec.rb'
|
||||
- 'spec/models/spree/adjustment_spec.rb'
|
||||
- 'spec/models/spree/asset_spec.rb'
|
||||
- 'spec/models/spree/line_item_spec.rb'
|
||||
- 'spec/models/spree/order_spec.rb'
|
||||
- 'spec/models/spree/variant_spec.rb'
|
||||
@@ -510,7 +494,7 @@ Rails/SkipsModelValidations:
|
||||
- 'spec/support/request/shop_workflow.rb'
|
||||
- 'spec/views/spree/shared/_order_details.html.haml_spec.rb'
|
||||
|
||||
# Offense count: 3
|
||||
# Offense count: 4
|
||||
# Configuration parameters: Include.
|
||||
# Include: app/models/**/*.rb
|
||||
Rails/UniqueValidationWithoutIndex:
|
||||
@@ -518,6 +502,7 @@ Rails/UniqueValidationWithoutIndex:
|
||||
- 'app/models/customer.rb'
|
||||
- 'app/models/exchange.rb'
|
||||
- 'app/models/spree/stock_item.rb'
|
||||
- 'app/models/spree/zone.rb'
|
||||
|
||||
# Offense count: 2
|
||||
# Configuration parameters: Environments.
|
||||
@@ -527,23 +512,29 @@ Rails/UnknownEnv:
|
||||
- 'app/models/spree/app_configuration_decorator.rb'
|
||||
- 'lib/spree/core/controller_helpers/ssl.rb'
|
||||
|
||||
# Offense count: 2
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle.
|
||||
# SupportedStyles: percent_q, bare_percent
|
||||
Style/BarePercentLiterals:
|
||||
Exclude:
|
||||
- 'spec/support/request/web_helper.rb'
|
||||
|
||||
# Offense count: 2
|
||||
Style/CaseEquality:
|
||||
Exclude:
|
||||
- 'app/helpers/angular_form_helper.rb'
|
||||
- 'spec/models/spree/payment_spec.rb'
|
||||
|
||||
# Offense count: 71
|
||||
# Offense count: 64
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: AutoCorrect, EnforcedStyle.
|
||||
# SupportedStyles: nested, compact
|
||||
Style/ClassAndModuleChildren:
|
||||
Exclude:
|
||||
- 'app/models/calculator/flat_percent_per_item.rb'
|
||||
- 'app/models/spree/concerns/payment_method_distributors.rb'
|
||||
- 'app/models/spree/gateway/migs.rb'
|
||||
- 'app/models/spree/gateway/pin.rb'
|
||||
- 'app/models/spree/preferences/file_configuration.rb'
|
||||
- 'app/models/spree/product_set.rb'
|
||||
- 'app/models/tag_rule/discount_order.rb'
|
||||
- 'app/models/tag_rule/filter_order_cycles.rb'
|
||||
@@ -601,11 +592,13 @@ Style/ClassAndModuleChildren:
|
||||
- 'app/serializers/api/variant_serializer.rb'
|
||||
- 'lib/open_food_network/locking.rb'
|
||||
- 'spec/controllers/spree/admin/base_controller_spec.rb'
|
||||
- 'spec/models/spree/payment_method_spec.rb'
|
||||
|
||||
# Offense count: 2
|
||||
# Offense count: 3
|
||||
Style/ClassVars:
|
||||
Exclude:
|
||||
- 'lib/open_food_network/rack_request_blocker.rb'
|
||||
- 'lib/spree/core/delegate_belongs_to.rb'
|
||||
|
||||
# Offense count: 4
|
||||
# Configuration parameters: EnforcedStyle.
|
||||
@@ -615,7 +608,7 @@ Style/FormatStringToken:
|
||||
- 'lib/open_food_network/sales_tax_report.rb'
|
||||
- 'spec/features/admin/bulk_order_management_spec.rb'
|
||||
|
||||
# Offense count: 847
|
||||
# Offense count: 829
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle.
|
||||
# SupportedStyles: always, always_true, never
|
||||
@@ -710,10 +703,6 @@ Style/FrozenStringLiteralComment:
|
||||
- 'app/controllers/spree/admin/zones_controller.rb'
|
||||
- 'app/controllers/spree/credit_cards_controller.rb'
|
||||
- 'app/controllers/spree/orders_controller.rb'
|
||||
- 'app/controllers/spree/store_controller.rb'
|
||||
- 'app/controllers/spree/user_passwords_controller.rb'
|
||||
- 'app/controllers/spree/user_registrations_controller.rb'
|
||||
- 'app/controllers/spree/user_sessions_controller.rb'
|
||||
- 'app/controllers/spree/users_controller.rb'
|
||||
- 'app/controllers/stripe/callbacks_controller.rb'
|
||||
- 'app/controllers/stripe/webhooks_controller.rb'
|
||||
@@ -781,11 +770,9 @@ Style/FrozenStringLiteralComment:
|
||||
- 'app/models/coordinator_fee.rb'
|
||||
- 'app/models/customer.rb'
|
||||
- 'app/models/distributor_shipping_method.rb'
|
||||
- 'app/models/enterprise.rb'
|
||||
- 'app/models/enterprise_fee.rb'
|
||||
- 'app/models/enterprise_fee_set.rb'
|
||||
- 'app/models/enterprise_group.rb'
|
||||
- 'app/models/enterprise_relationship.rb'
|
||||
- 'app/models/enterprise_relationship_permission.rb'
|
||||
- 'app/models/enterprise_role.rb'
|
||||
- 'app/models/enterprise_set.rb'
|
||||
@@ -796,7 +783,6 @@ Style/FrozenStringLiteralComment:
|
||||
- 'app/models/model_set.rb'
|
||||
- 'app/models/order_cycle.rb'
|
||||
- 'app/models/order_cycle_set.rb'
|
||||
- 'app/models/order_updater.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'
|
||||
@@ -824,16 +810,12 @@ Style/FrozenStringLiteralComment:
|
||||
- 'app/models/spree/calculator_decorator.rb'
|
||||
- 'app/models/spree/classification_decorator.rb'
|
||||
- 'app/models/spree/concerns/payment_method_distributors.rb'
|
||||
- 'app/models/spree/credit_card_decorator.rb'
|
||||
- 'app/models/spree/gateway/migs.rb'
|
||||
- 'app/models/spree/gateway/pin.rb'
|
||||
- 'app/models/spree/gateway/stripe_connect.rb'
|
||||
- 'app/models/spree/gateway_decorator.rb'
|
||||
- 'app/models/spree/image_decorator.rb'
|
||||
- 'app/models/spree/line_item_decorator.rb'
|
||||
- 'app/models/spree/option_type_decorator.rb'
|
||||
- 'app/models/spree/order_decorator.rb'
|
||||
- 'app/models/spree/payment_method_decorator.rb'
|
||||
- 'app/models/spree/preferences/file_configuration.rb'
|
||||
- 'app/models/spree/price_decorator.rb'
|
||||
- 'app/models/spree/product_decorator.rb'
|
||||
@@ -842,7 +824,6 @@ Style/FrozenStringLiteralComment:
|
||||
- 'app/models/spree/product_set.rb'
|
||||
- 'app/models/spree/property.rb'
|
||||
- 'app/models/spree/shipping_method_decorator.rb'
|
||||
- 'app/models/spree/stock_location_decorator.rb'
|
||||
- 'app/models/spree/tax_rate_decorator.rb'
|
||||
- 'app/models/spree/taxon_decorator.rb'
|
||||
- 'app/models/spree/user.rb'
|
||||
@@ -1125,7 +1106,6 @@ Style/FrozenStringLiteralComment:
|
||||
- 'spec/controllers/api/taxonomies_controller_spec.rb'
|
||||
- 'spec/controllers/api/taxons_controller_spec.rb'
|
||||
- 'spec/controllers/api/variants_controller_spec.rb'
|
||||
- 'spec/controllers/base_controller2_spec.rb'
|
||||
- 'spec/controllers/base_controller_spec.rb'
|
||||
- 'spec/controllers/cart_controller_spec.rb'
|
||||
- 'spec/controllers/checkout_controller_spec.rb'
|
||||
@@ -1169,6 +1149,8 @@ Style/FrozenStringLiteralComment:
|
||||
- 'spec/factories/product_factory.rb'
|
||||
- 'spec/factories/shipment_factory.rb'
|
||||
- 'spec/factories/shipping_method_factory.rb'
|
||||
- 'spec/factories/state_factory.rb'
|
||||
- 'spec/factories/stock_movement_factory.rb'
|
||||
- 'spec/factories/subscription_factory.rb'
|
||||
- 'spec/factories/tag_rule_factory.rb'
|
||||
- 'spec/factories/user_factory.rb'
|
||||
@@ -1323,7 +1305,6 @@ Style/FrozenStringLiteralComment:
|
||||
- 'spec/models/exchange_spec.rb'
|
||||
- 'spec/models/model_set_spec.rb'
|
||||
- 'spec/models/order_cycle_spec.rb'
|
||||
- 'spec/models/order_updater_spec.rb'
|
||||
- 'spec/models/product_import/entry_processor_spec.rb'
|
||||
- 'spec/models/product_import/inventory_reset_strategy_spec.rb'
|
||||
- 'spec/models/product_import/reset_absent_spec.rb'
|
||||
@@ -1461,6 +1442,7 @@ Style/FrozenStringLiteralComment:
|
||||
- 'spec/views/spree/admin/orders/edit.html.haml_spec.rb'
|
||||
- 'spec/views/spree/admin/orders/index.html.haml_spec.rb'
|
||||
- 'spec/views/spree/admin/payment_methods/index.html.haml_spec.rb'
|
||||
- 'spec/views/spree/admin/shared/_order_links.html.haml_spec.rb'
|
||||
|
||||
# Offense count: 48
|
||||
# Configuration parameters: MinBodyLength.
|
||||
@@ -1491,18 +1473,21 @@ Style/GuardClause:
|
||||
- 'spec/support/request/distribution_helper.rb'
|
||||
- 'spec/support/request/shop_workflow.rb'
|
||||
|
||||
# Offense count: 54
|
||||
# Offense count: 66
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, UseHashRocketsWithSymbolValues, PreferHashRocketsForNonAlnumEndingSymbols.
|
||||
# SupportedStyles: ruby19, hash_rockets, no_mixed_keys, ruby19_no_mixed_keys
|
||||
Style/HashSyntax:
|
||||
Exclude:
|
||||
- 'spec/factories/stock_location_factory.rb'
|
||||
- 'spec/models/spree/credit_card_spec.rb'
|
||||
- 'spec/models/spree/payment_spec.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Offense count: 2
|
||||
Style/MissingRespondToMissing:
|
||||
Exclude:
|
||||
- 'app/helpers/application_helper.rb'
|
||||
- 'app/models/spree/gateway.rb'
|
||||
|
||||
# Offense count: 2
|
||||
Style/MixinUsage:
|
||||
@@ -1510,7 +1495,7 @@ Style/MixinUsage:
|
||||
- 'lib/open_food_network/orders_and_fulfillments_report.rb'
|
||||
- 'spec/lib/open_food_network/packing_report_spec.rb'
|
||||
|
||||
# Offense count: 39
|
||||
# Offense count: 37
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: AutoCorrect, EnforcedStyle, IgnoredMethods.
|
||||
# SupportedStyles: predicate, comparison
|
||||
@@ -1521,7 +1506,6 @@ Style/NumericPredicate:
|
||||
- 'app/controllers/spree/orders_controller.rb'
|
||||
- 'app/helpers/checkout_helper.rb'
|
||||
- 'app/helpers/shared_helper.rb'
|
||||
- 'app/models/order_updater.rb'
|
||||
- 'app/models/product_import/product_importer.rb'
|
||||
- 'app/models/product_import/spreadsheet_entry.rb'
|
||||
- 'app/models/spree/adjustment_decorator.rb'
|
||||
@@ -1548,6 +1532,18 @@ Style/RaiseArgs:
|
||||
Exclude:
|
||||
- 'spec/controllers/checkout_controller_spec.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
Style/RandomWithOffset:
|
||||
Exclude:
|
||||
- 'spec/factories.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
Style/RedundantPercentQ:
|
||||
Exclude:
|
||||
- 'spec/support/request/web_helper.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, AllowInnerSlashes.
|
||||
@@ -1556,6 +1552,14 @@ Style/RegexpLiteral:
|
||||
Exclude:
|
||||
- 'lib/spree/core/controller_helpers/auth.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle.
|
||||
# SupportedStyles: implicit, explicit
|
||||
Style/RescueStandardError:
|
||||
Exclude:
|
||||
- 'lib/spree/core/delegate_belongs_to.rb'
|
||||
|
||||
# Offense count: 231
|
||||
Style/Send:
|
||||
Exclude:
|
||||
|
||||
@@ -22,7 +22,7 @@ GIT
|
||||
|
||||
GIT
|
||||
remote: https://github.com/openfoodfoundation/spree.git
|
||||
revision: 0b0c422369c82b6dd7e7cb627a24e3a9fca19a6c
|
||||
revision: cbb24a6ed701166ffaf2ab60a402154100d74766
|
||||
branch: 2-1-0-stable
|
||||
specs:
|
||||
spree_core (2.1.0)
|
||||
@@ -148,7 +148,7 @@ GEM
|
||||
nokogiri (>= 1.4.4)
|
||||
uuidtools (~> 2.1)
|
||||
bcrypt (3.1.13)
|
||||
bugsnag (6.16.0)
|
||||
bugsnag (6.17.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
builder (3.1.4)
|
||||
byebug (11.0.1)
|
||||
@@ -204,7 +204,7 @@ GEM
|
||||
activerecord (>= 3.2.0, < 5.0)
|
||||
fog (~> 1.0)
|
||||
rails (>= 3.2.0, < 5.0)
|
||||
ddtrace (0.39.0)
|
||||
ddtrace (0.40.0)
|
||||
msgpack
|
||||
debugger-linecache (1.2.0)
|
||||
delayed_job (4.1.8)
|
||||
@@ -439,7 +439,7 @@ GEM
|
||||
json_spec (1.1.5)
|
||||
multi_json (~> 1.0)
|
||||
rspec (>= 2.0, < 4.0)
|
||||
jwt (2.2.1)
|
||||
jwt (2.2.2)
|
||||
kaminari (0.14.1)
|
||||
actionpack (>= 3.0.0)
|
||||
activesupport (>= 3.0.0)
|
||||
|
||||
@@ -2,15 +2,6 @@ Darkswarm.controller "OrderCycleCtrl", ($scope, $rootScope, $timeout, OrderCycle
|
||||
$scope.order_cycle = OrderCycle.order_cycle
|
||||
$scope.OrderCycle = OrderCycle
|
||||
|
||||
# Timeout forces this to be evaluated after everything is loaded
|
||||
# This is a hack. We should probably write our own "popover" directive
|
||||
# That takes an expression instead of a trigger, and binds to that
|
||||
$timeout =>
|
||||
$rootScope.$broadcast 'orderCycleSelected'
|
||||
if !$scope.OrderCycle.selected()
|
||||
$("#order_cycle_id").trigger("openTrigger")
|
||||
|
||||
|
||||
Darkswarm.controller "OrderCycleChangeCtrl", ($scope, $rootScope, $timeout, OrderCycle, Products, Variants, Cart, ChangeableOrdersAlert) ->
|
||||
# Track previous order cycle id for use with revertOrderCycle()
|
||||
$scope.previous_order_cycle_id = OrderCycle.order_cycle.order_cycle_id
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Darkswarm.controller "PageSelectionCtrl", ($scope, $location) ->
|
||||
Darkswarm.controller "PageSelectionCtrl", ($scope, $rootScope, $location) ->
|
||||
$scope.selectedPage = ->
|
||||
# The path looks like `/contact` for the URL `https://ofn.org/shop#/contact`.
|
||||
# We remove the slash at the beginning.
|
||||
@@ -15,3 +15,8 @@ Darkswarm.controller "PageSelectionCtrl", ($scope, $location) ->
|
||||
$scope.whitelistPages = (pages) ->
|
||||
$scope.whitelist = pages
|
||||
$scope.lastPage = pages[0]
|
||||
|
||||
# when an order cycle is changed, ensure the shop tab is active to save a click
|
||||
$rootScope.$on "orderCycleSelected", ->
|
||||
if $scope.selectedPage() != "shop"
|
||||
$location.path("shop")
|
||||
|
||||
@@ -12,6 +12,11 @@ Darkswarm.controller "ProductsCtrl", ($scope, $sce, $filter, $rootScope, Product
|
||||
$scope.supplied_properties = null
|
||||
$scope.showFilterSidebar = false
|
||||
|
||||
# Update filters after initial load of shop tab
|
||||
$timeout =>
|
||||
$scope.update_filters()
|
||||
|
||||
# Update filters when order cycle changed
|
||||
$rootScope.$on "orderCycleSelected", ->
|
||||
$scope.update_filters()
|
||||
$scope.clearAll()
|
||||
|
||||
@@ -16,8 +16,5 @@ window.Darkswarm = angular.module("Darkswarm", [
|
||||
$httpProvider.defaults.headers['common']['X-Requested-With'] = 'XMLHttpRequest'
|
||||
$httpProvider.defaults.headers.common.Accept = "application/json, text/javascript, */*"
|
||||
|
||||
# This allows us to trigger these two events on tooltips
|
||||
$tooltipProvider.setTriggers( 'openTrigger': 'closeTrigger' )
|
||||
|
||||
# We manually handle our scrolling
|
||||
$anchorScrollProvider.disableAutoScrolling()
|
||||
|
||||
@@ -43,7 +43,7 @@ Darkswarm.directive 'mapSearch', ($timeout, Search) ->
|
||||
# When the map loads, and we have a search from ?query, perform that search
|
||||
scope.performUrlSearch = (map) ->
|
||||
google.maps.event.addListenerOnce map, "idle", =>
|
||||
google.maps.event.trigger(scope.input, 'focus');
|
||||
google.maps.event.trigger(scope.input, 'focus',{});
|
||||
google.maps.event.trigger(scope.input, 'keydown', {keyCode: 13});
|
||||
|
||||
# Bias the SearchBox results towards places that are within the bounds of the
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Darkswarm.factory 'Cart', (CurrentOrder, Variants, $timeout, $http, $modal, $rootScope, $resource, localStorageService, RailsFlashLoader) ->
|
||||
Darkswarm.factory 'Cart', (CurrentOrder, Variants, $timeout, $http, $modal, $rootScope, $resource, localStorageService, Messages) ->
|
||||
# Handles syncing of current cart/order state to server
|
||||
new class Cart
|
||||
dirty: false
|
||||
@@ -50,7 +50,7 @@ Darkswarm.factory 'Cart', (CurrentOrder, Variants, $timeout, $http, $modal, $roo
|
||||
@popQueue() if @update_enqueued
|
||||
|
||||
.error (response, status)=>
|
||||
RailsFlashLoader.loadFlash({error: t('js.cart.add_to_cart_failed')})
|
||||
Messages.flash({error: t('js.cart.add_to_cart_failed')})
|
||||
@update_running = false
|
||||
|
||||
compareAndNotifyStockLevels: (stockLevels) =>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Darkswarm.factory 'Checkout', ($injector, CurrentOrder, ShippingMethods, StripeElements, PaymentMethods, $http, Navigation, CurrentHub, RailsFlashLoader, Loading)->
|
||||
Darkswarm.factory 'Checkout', ($injector, CurrentOrder, ShippingMethods, StripeElements, PaymentMethods, $http, Navigation, CurrentHub, Messages)->
|
||||
new class Checkout
|
||||
errors: {}
|
||||
secrets: {}
|
||||
@@ -13,7 +13,7 @@ Darkswarm.factory 'Checkout', ($injector, CurrentOrder, ShippingMethods, StripeE
|
||||
@submit()
|
||||
|
||||
submit: =>
|
||||
Loading.message = t 'submitting_order'
|
||||
Messages.loading(t 'submitting_order')
|
||||
$http.put('/checkout.json', {order: @preprocess()})
|
||||
.then (response) =>
|
||||
Navigation.go response.data.path
|
||||
@@ -39,8 +39,7 @@ Darkswarm.factory 'Checkout', ($injector, CurrentOrder, ShippingMethods, StripeE
|
||||
@loadFlash(response.data.flash)
|
||||
|
||||
loadFlash: (flash) =>
|
||||
Loading.clear()
|
||||
RailsFlashLoader.loadFlash(flash)
|
||||
Messages.flash(flash)
|
||||
|
||||
# Rails wants our Spree::Address data to be provided with _attributes
|
||||
preprocess: ->
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Darkswarm.factory 'CreditCard', ($injector, $rootScope, CreditCards, StripeElements, Navigation, $http, RailsFlashLoader, Loading)->
|
||||
Darkswarm.factory 'CreditCard', ($injector, $rootScope, CreditCards, StripeElements, Navigation, $http, Messages)->
|
||||
new class CreditCard
|
||||
visible: false
|
||||
errors: {}
|
||||
@@ -12,16 +12,15 @@ Darkswarm.factory 'CreditCard', ($injector, $rootScope, CreditCards, StripeEleme
|
||||
params = @process_params()
|
||||
$http.put('/credit_cards/new_from_token', params )
|
||||
.success (data, status) =>
|
||||
Loading.clear()
|
||||
Messages.clear()
|
||||
@reset()
|
||||
CreditCards.add(data)
|
||||
.error (response, status) =>
|
||||
if response.path
|
||||
Navigation.go response.path
|
||||
else
|
||||
Loading.clear()
|
||||
@errors = response.errors
|
||||
RailsFlashLoader.loadFlash(response.flash)
|
||||
Messages.flash(response.flash)
|
||||
|
||||
setFullName: ->
|
||||
@secrets.name = "#{@secrets.first_name} #{@secrets.last_name}"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Darkswarm.factory 'CreditCards', ($http, $filter, savedCreditCards, RailsFlashLoader)->
|
||||
Darkswarm.factory 'CreditCards', ($http, $filter, savedCreditCards, Messages)->
|
||||
new class CreditCard
|
||||
saved: $filter('orderBy')(savedCreditCards,'-is_default')
|
||||
|
||||
@@ -10,6 +10,6 @@ Darkswarm.factory 'CreditCards', ($http, $filter, savedCreditCards, RailsFlashLo
|
||||
for othercard in @saved when othercard != card
|
||||
othercard.is_default = false
|
||||
$http.put("/credit_cards/#{card.id}", is_default: true).then (data) ->
|
||||
RailsFlashLoader.loadFlash({success: t('js.default_card_updated')})
|
||||
Messages.success(t('js.default_card_updated'))
|
||||
, (response) ->
|
||||
RailsFlashLoader.loadFlash({error: response.data.flash.error})
|
||||
Messages.flash(response.data.flash)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
angular.module("Darkswarm").factory 'Customer', ($resource, RailsFlashLoader) ->
|
||||
angular.module("Darkswarm").factory 'Customer', ($resource, Messages) ->
|
||||
Customer = $resource('/api/customers/:id/:action.json', {}, {
|
||||
'index':
|
||||
method: 'GET'
|
||||
@@ -13,8 +13,8 @@ angular.module("Darkswarm").factory 'Customer', ($resource, RailsFlashLoader) ->
|
||||
|
||||
Customer.prototype.update = ->
|
||||
@$update().then (response) =>
|
||||
RailsFlashLoader.loadFlash({success: t('js.changes_saved')})
|
||||
Messages.success(t('js.changes_saved'))
|
||||
, (response) =>
|
||||
RailsFlashLoader.loadFlash({error: response.data.error})
|
||||
Messages.error(response.data.error)
|
||||
|
||||
Customer
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Darkswarm.factory "Loading", ->
|
||||
new class Loading
|
||||
message: null
|
||||
message: null
|
||||
clear: =>
|
||||
@message = null
|
||||
|
||||
17
app/assets/javascripts/darkswarm/services/messages.js.coffee
Normal file
17
app/assets/javascripts/darkswarm/services/messages.js.coffee
Normal file
@@ -0,0 +1,17 @@
|
||||
Darkswarm.factory "Messages", (Loading, RailsFlashLoader)->
|
||||
new class Messages
|
||||
loading: (message) ->
|
||||
Loading.message = message
|
||||
|
||||
success: (message) ->
|
||||
@flash(success: message)
|
||||
|
||||
error: (message) ->
|
||||
@flash(error: message)
|
||||
|
||||
flash: (flash) ->
|
||||
@clear()
|
||||
RailsFlashLoader.loadFlash(flash)
|
||||
|
||||
clear: ->
|
||||
Loading.clear()
|
||||
@@ -1,4 +1,4 @@
|
||||
Darkswarm.factory 'StripeElements', ($rootScope, Loading, RailsFlashLoader) ->
|
||||
Darkswarm.factory 'StripeElements', ($rootScope, Messages) ->
|
||||
new class StripeElements
|
||||
# These are both set from the StripeElements directive
|
||||
stripe: null
|
||||
@@ -8,39 +8,49 @@ Darkswarm.factory 'StripeElements', ($rootScope, Loading, RailsFlashLoader) ->
|
||||
requestToken: (secrets, submit, loading_message = t("processing_payment")) ->
|
||||
return unless @stripe? && @card?
|
||||
|
||||
Loading.message = loading_message
|
||||
Messages.loading loading_message
|
||||
cardData = @makeCardData(secrets)
|
||||
|
||||
@stripe.createToken(@card, cardData).then (response) =>
|
||||
if(response.error)
|
||||
Loading.clear()
|
||||
RailsFlashLoader.loadFlash({error: t("error") + ": #{response.error.message}"})
|
||||
@triggerAngularDigest()
|
||||
console.error(JSON.stringify(response.error))
|
||||
@reportError(response.error, t("error") + ": #{response.error.message}")
|
||||
else
|
||||
secrets.token = response.token.id
|
||||
secrets.cc_type = @mapTokenApiCardBrand(response.token.card.brand)
|
||||
secrets.card = response.token.card
|
||||
submit()
|
||||
.catch (response) =>
|
||||
# Stripe handles errors in the response above. This code may never be
|
||||
# reached. But if we get here, we want to know.
|
||||
@reportError(response, t("js.stripe_elements.unknown_error_from_stripe"))
|
||||
throw response
|
||||
|
||||
# Create Payment Method to be used with the Stripe Payment Intents API
|
||||
createPaymentMethod: (secrets, submit, loading_message = t("processing_payment")) ->
|
||||
return unless @stripe? && @card?
|
||||
|
||||
Loading.message = loading_message
|
||||
Messages.loading loading_message
|
||||
cardData = @makeCardData(secrets)
|
||||
|
||||
@stripe.createPaymentMethod({ type: 'card', card: @card }, @card, cardData).then (response) =>
|
||||
if(response.error)
|
||||
Loading.clear()
|
||||
RailsFlashLoader.loadFlash({error: t("error") + ": #{response.error.message}"})
|
||||
@triggerAngularDigest()
|
||||
console.error(JSON.stringify(response.error))
|
||||
@reportError(response.error, t("error") + ": #{response.error.message}")
|
||||
else
|
||||
secrets.token = response.paymentMethod.id
|
||||
secrets.cc_type = @mapPaymentMethodsApiCardBrand(response.paymentMethod.card.brand)
|
||||
secrets.card = response.paymentMethod.card
|
||||
submit()
|
||||
.catch (response) =>
|
||||
# Stripe handles errors in the response above. This code may never be
|
||||
# reached. But if we get here, we want to know.
|
||||
@reportError(response, t("js.stripe_elements.unknown_error_from_stripe"))
|
||||
throw response
|
||||
|
||||
reportError: (error, messageForUser) ->
|
||||
Messages.error(messageForUser)
|
||||
@triggerAngularDigest()
|
||||
console.error(error)
|
||||
Bugsnag.notify(new Error(JSON.stringify(error)))
|
||||
|
||||
triggerAngularDigest: ->
|
||||
# $evalAsync is improved way of triggering a digest without calling $apply
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
.report__table {
|
||||
margin-top: 2em;
|
||||
}
|
||||
|
||||
.report__message {
|
||||
margin-top: 2em;
|
||||
border: 1px solid $pale-blue;
|
||||
@@ -10,3 +11,7 @@
|
||||
padding: .5em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.customer-names-tip {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
@import '../admin/variables';
|
||||
|
||||
/* -------------------------------------
|
||||
* GLOBAL
|
||||
*------------------------------------- */
|
||||
|
||||
45
app/assets/stylesheets/mail/payments_list.scss
Normal file
45
app/assets/stylesheets/mail/payments_list.scss
Normal file
@@ -0,0 +1,45 @@
|
||||
@import "../admin/variables";
|
||||
|
||||
// payment list, used in both invoice pdfs and order confirmation emails
|
||||
|
||||
.payments-list {
|
||||
width: 100%;
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
font-size: 12px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
td {
|
||||
padding: 5px;
|
||||
border-bottom: 1px solid $medium-grey;
|
||||
|
||||
.payment-method-name {
|
||||
display: block;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.payment-method-description {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
thead th {
|
||||
border-bottom: 1px solid $medium-grey;
|
||||
padding: 10px 5px 5px;
|
||||
text-transform: uppercase;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.amount {
|
||||
text-align: right;
|
||||
padding-right: 15px;
|
||||
}
|
||||
|
||||
.payment-state {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.payment-state-value {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
module Admin
|
||||
class OrderCyclesController < ResourceController
|
||||
include OrderCyclesHelper
|
||||
include PaperTrailLogging
|
||||
|
||||
prepend_before_action :set_order_cycle_id, only: [:incoming, :outgoing]
|
||||
before_action :load_data_for_index, only: :index
|
||||
|
||||
@@ -3,6 +3,8 @@ require 'order_management/subscriptions/proxy_order_syncer'
|
||||
|
||||
module Admin
|
||||
class SchedulesController < ResourceController
|
||||
include PaperTrailLogging
|
||||
|
||||
before_action :adapt_params, only: [:update]
|
||||
before_action :editable_order_cycle_ids_for_create, only: [:create]
|
||||
before_action :editable_order_cycle_ids_for_update, only: [:update]
|
||||
@@ -140,7 +142,7 @@ module Admin
|
||||
end
|
||||
|
||||
def permitted_resource_params
|
||||
params.require(:schedule).permit(:id, :name)
|
||||
params.require(:schedule).permit(:id, :name, order_cycle_ids: [])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
17
app/controllers/concerns/paper_trail_logging.rb
Normal file
17
app/controllers/concerns/paper_trail_logging.rb
Normal file
@@ -0,0 +1,17 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# This concern adds additional Papertrail logging options so that the id of the
|
||||
# user that modified the record is also logged.
|
||||
# See: https://github.com/paper-trail-gem/paper_trail#setting-whodunnit-with-a-controller-callback
|
||||
|
||||
module PaperTrailLogging
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
before_action :set_paper_trail_whodunnit
|
||||
end
|
||||
|
||||
def user_for_paper_trail
|
||||
spree_current_user
|
||||
end
|
||||
end
|
||||
@@ -51,7 +51,7 @@ module Spree
|
||||
end
|
||||
|
||||
def load_order
|
||||
@order = Order.find_by_number!(params[:order_id], include: :adjustments)
|
||||
@order = Order.find_by!({ number: params[:order_id] }, include: :adjustments)
|
||||
end
|
||||
|
||||
def check_authorization
|
||||
|
||||
@@ -80,7 +80,7 @@ module Spree
|
||||
|
||||
def resend
|
||||
Spree::OrderMailer.confirm_email_for_customer(@order.id, true).deliver
|
||||
flash[:success] = t(:order_email_resent)
|
||||
flash[:success] = t('admin.orders.order_email_resent')
|
||||
|
||||
respond_with(@order) { |format| format.html { redirect_to :back } }
|
||||
end
|
||||
|
||||
@@ -178,7 +178,7 @@ module Spree
|
||||
return nil if parent_data.blank?
|
||||
|
||||
@parent ||= parent_data[:model_class].
|
||||
public_send("find_by_#{parent_data[:find_by]}", params["#{model_name}_id"])
|
||||
public_send("find_by", parent_data[:find_by] => params["#{model_name}_id"])
|
||||
instance_variable_set("@#{model_name}", @parent)
|
||||
end
|
||||
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'cancan'
|
||||
require 'spree/core/controller_helpers/auth'
|
||||
require 'spree/core/controller_helpers/respond_with'
|
||||
require 'spree/core/controller_helpers/common'
|
||||
require 'spree/core/controller_helpers/ssl'
|
||||
|
||||
module Spree
|
||||
class BaseController < ApplicationController
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spree/core/controller_helpers/order'
|
||||
|
||||
module Spree
|
||||
class StoreController < Spree::BaseController
|
||||
layout 'darkswarm'
|
||||
|
||||
@@ -4,4 +4,8 @@ module OrderHelper
|
||||
def last_payment_method(order)
|
||||
OrderPaymentFinder.new(order).last_payment&.payment_method
|
||||
end
|
||||
|
||||
def outstanding_balance_label(order)
|
||||
order.outstanding_balance.negative? ? t(:credit_owed) : t(:balance_due)
|
||||
end
|
||||
end
|
||||
|
||||
19
app/helpers/spree/admin/images_helper.rb
Normal file
19
app/helpers/spree/admin/images_helper.rb
Normal file
@@ -0,0 +1,19 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Spree
|
||||
module Admin
|
||||
module ImagesHelper
|
||||
def options_text_for(image)
|
||||
if image.viewable.is_a?(Spree::Variant)
|
||||
if image.viewable.is_master?
|
||||
I18n.t(:all)
|
||||
else
|
||||
image.viewable.options_text
|
||||
end
|
||||
else
|
||||
I18n.t(:all)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -11,7 +11,7 @@ module Spree
|
||||
checkout_zone = Zone.find_by(name: Spree::Config[:checkout_zone])
|
||||
|
||||
countries = if checkout_zone && checkout_zone.kind == 'country'
|
||||
checkout_zone.country_list
|
||||
checkout_zone.countries
|
||||
else
|
||||
Country.includes(:states).all
|
||||
end
|
||||
|
||||
@@ -5,6 +5,7 @@ module Spree
|
||||
helper HtmlHelper
|
||||
helper ::CheckoutHelper
|
||||
helper SpreeCurrencyHelper
|
||||
helper Spree::Admin::PaymentsHelper
|
||||
helper OrderHelper
|
||||
include I18nHelper
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ class SubscriptionMailer < Spree::BaseMailer
|
||||
helper CheckoutHelper
|
||||
helper ShopMailHelper
|
||||
helper OrderHelper
|
||||
helper Spree::Admin::PaymentsHelper
|
||||
include I18nHelper
|
||||
|
||||
def confirmation_email(order)
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# frozen_string_literal: false
|
||||
|
||||
require 'spree/core/s3_support'
|
||||
|
||||
class Enterprise < ActiveRecord::Base
|
||||
SELLS = %w(unspecified none own any).freeze
|
||||
ENTERPRISE_SEARCH_RADIUS = 100
|
||||
@@ -6,6 +10,7 @@ class Enterprise < ActiveRecord::Base
|
||||
preference :shopfront_closed_message, :text, default: ""
|
||||
preference :shopfront_taxon_order, :string, default: ""
|
||||
preference :shopfront_order_cycle_order, :string, default: "orders_close_at"
|
||||
preference :show_customer_names_to_suppliers, :boolean, default: false
|
||||
|
||||
# This is hopefully a temporary measure, pending the arrival of multiple named inventories
|
||||
# for shops. We need this here to allow hubs to restrict visible variants to only those in
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class EnterpriseRelationship < ActiveRecord::Base
|
||||
belongs_to :parent, class_name: 'Enterprise', touch: true
|
||||
belongs_to :child, class_name: 'Enterprise', touch: true
|
||||
|
||||
177
app/models/spree/adjustment.rb
Normal file
177
app/models/spree/adjustment.rb
Normal file
@@ -0,0 +1,177 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spree/localized_number'
|
||||
require 'concerns/adjustment_scopes'
|
||||
|
||||
# Adjustments represent a change to the +item_total+ of an Order. Each adjustment
|
||||
# has an +amount+ that can be either positive or negative.
|
||||
#
|
||||
# Adjustments can be open/closed/finalized
|
||||
#
|
||||
# Once an adjustment is finalized, it cannot be changed, but an adjustment can
|
||||
# toggle between open/closed as needed
|
||||
#
|
||||
# Boolean attributes:
|
||||
#
|
||||
# +mandatory+
|
||||
#
|
||||
# If this flag is set to true then it means the the charge is required and will not
|
||||
# be removed from the order, even if the amount is zero. In other words a record
|
||||
# will be created even if the amount is zero. This is useful for representing things
|
||||
# such as shipping and tax charges where you may want to make it explicitly clear
|
||||
# that no charge was made for such things.
|
||||
#
|
||||
# +eligible?+
|
||||
#
|
||||
# This boolean attributes stores whether this adjustment is currently eligible
|
||||
# for its order. Only eligible adjustments count towards the order's adjustment
|
||||
# total. This allows an adjustment to be preserved if it becomes ineligible so
|
||||
# it might be reinstated.
|
||||
module Spree
|
||||
class Adjustment < ActiveRecord::Base
|
||||
extend Spree::LocalizedNumber
|
||||
|
||||
# Deletion of metadata is handled in the database.
|
||||
# So we don't need the option `dependent: :destroy` as long as
|
||||
# AdjustmentMetadata has no destroy logic itself.
|
||||
has_one :metadata, class_name: 'AdjustmentMetadata'
|
||||
|
||||
belongs_to :adjustable, polymorphic: true
|
||||
belongs_to :source, polymorphic: true
|
||||
belongs_to :originator, polymorphic: true
|
||||
belongs_to :tax_rate, -> { where spree_adjustments: { originator_type: 'Spree::TaxRate' } },
|
||||
foreign_key: 'originator_id'
|
||||
|
||||
validates :label, presence: true
|
||||
validates :amount, numericality: true
|
||||
|
||||
after_save :update_adjustable
|
||||
after_destroy :update_adjustable
|
||||
|
||||
state_machine :state, initial: :open do
|
||||
event :close do
|
||||
transition from: :open, to: :closed
|
||||
end
|
||||
|
||||
event :open do
|
||||
transition from: :closed, to: :open
|
||||
end
|
||||
|
||||
event :finalize do
|
||||
transition from: [:open, :closed], to: :finalized
|
||||
end
|
||||
end
|
||||
|
||||
scope :tax, -> { where(originator_type: 'Spree::TaxRate', adjustable_type: 'Spree::Order') }
|
||||
scope :price, -> { where(adjustable_type: 'Spree::LineItem') }
|
||||
scope :optional, -> { where(mandatory: false) }
|
||||
scope :charge, -> { where('amount >= 0') }
|
||||
scope :credit, -> { where('amount < 0') }
|
||||
scope :return_authorization, -> { where(source_type: "Spree::ReturnAuthorization") }
|
||||
|
||||
scope :enterprise_fee, -> { where(originator_type: 'EnterpriseFee') }
|
||||
scope :admin, -> { where(source_type: nil, originator_type: nil) }
|
||||
scope :included_tax, -> {
|
||||
where(originator_type: 'Spree::TaxRate', adjustable_type: 'Spree::LineItem')
|
||||
}
|
||||
|
||||
scope :with_tax, -> { where('spree_adjustments.included_tax <> 0') }
|
||||
scope :without_tax, -> { where('spree_adjustments.included_tax = 0') }
|
||||
scope :payment_fee, -> { where(AdjustmentScopes::PAYMENT_FEE_SCOPE) }
|
||||
scope :shipping, -> { where(AdjustmentScopes::SHIPPING_SCOPE) }
|
||||
scope :eligible, -> { where(AdjustmentScopes::ELIGIBLE_SCOPE) }
|
||||
|
||||
localize_number :amount
|
||||
|
||||
# Update the boolean _eligible_ attribute which determines which adjustments
|
||||
# count towards the order's adjustment_total.
|
||||
def set_eligibility
|
||||
result = mandatory || (amount != 0 && eligible_for_originator?)
|
||||
update_column(:eligible, result)
|
||||
end
|
||||
|
||||
# Allow originator of the adjustment to perform an additional eligibility of the adjustment
|
||||
# Should return _true_ if originator is absent or doesn't implement _eligible?_
|
||||
def eligible_for_originator?
|
||||
return true if originator.nil?
|
||||
|
||||
!originator.respond_to?(:eligible?) || originator.eligible?(source)
|
||||
end
|
||||
|
||||
# Update both the eligibility and amount of the adjustment. Adjustments
|
||||
# delegate updating of amount to their Originator when present, but only if
|
||||
# +locked+ is false. Adjustments that are +locked+ will never change their amount.
|
||||
#
|
||||
# Adjustments delegate updating of amount to their Originator when present,
|
||||
# but only if when they're in "open" state, closed or finalized adjustments
|
||||
# are not recalculated.
|
||||
#
|
||||
# It receives +calculable+ as the updated source here so calculations can be
|
||||
# performed on the current values of that source. If we used +source+ it
|
||||
# could load the old record from db for the association. e.g. when updating
|
||||
# more than on line items at once via accepted_nested_attributes the order
|
||||
# object on the association would be in a old state and therefore the
|
||||
# adjustment calculations would not performed on proper values
|
||||
def update!(calculable = nil)
|
||||
return if immutable?
|
||||
|
||||
# Fix for Spree issue #3381
|
||||
# If we attempt to call 'source' before the reload, then source is currently
|
||||
# the order object. After calling a reload, the source is the Shipment.
|
||||
reload
|
||||
originator.update_adjustment(self, calculable || source) if originator.present?
|
||||
set_eligibility
|
||||
end
|
||||
|
||||
def currency
|
||||
adjustable ? adjustable.currency : Spree::Config[:currency]
|
||||
end
|
||||
|
||||
def display_amount
|
||||
Spree::Money.new(amount, currency: currency)
|
||||
end
|
||||
|
||||
def immutable?
|
||||
state != "open"
|
||||
end
|
||||
|
||||
def set_included_tax!(rate)
|
||||
tax = amount - (amount / (1 + rate))
|
||||
set_absolute_included_tax! tax
|
||||
end
|
||||
|
||||
def set_absolute_included_tax!(tax)
|
||||
# This rubocop issue can now fixed by renaming Adjustment#update! to something else,
|
||||
# then AR's update! can be used instead of update_attributes!
|
||||
# rubocop:disable Rails/ActiveRecordAliases
|
||||
update_attributes! included_tax: tax.round(2)
|
||||
# rubocop:enable Rails/ActiveRecordAliases
|
||||
end
|
||||
|
||||
def display_included_tax
|
||||
Spree::Money.new(included_tax, currency: currency)
|
||||
end
|
||||
|
||||
def has_tax?
|
||||
included_tax.positive?
|
||||
end
|
||||
|
||||
def self.without_callbacks
|
||||
skip_callback :save, :after, :update_adjustable
|
||||
skip_callback :destroy, :after, :update_adjustable
|
||||
|
||||
result = yield
|
||||
ensure
|
||||
set_callback :save, :after, :update_adjustable
|
||||
set_callback :destroy, :after, :update_adjustable
|
||||
|
||||
result
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def update_adjustable
|
||||
adjustable.update! if adjustable.is_a? Order
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,62 +0,0 @@
|
||||
require 'spree/localized_number'
|
||||
require 'concerns/adjustment_scopes'
|
||||
|
||||
module Spree
|
||||
Adjustment.class_eval do
|
||||
extend Spree::LocalizedNumber
|
||||
|
||||
# Deletion of metadata is handled in the database.
|
||||
# So we don't need the option `dependent: :destroy` as long as
|
||||
# AdjustmentMetadata has no destroy logic itself.
|
||||
has_one :metadata, class_name: 'AdjustmentMetadata'
|
||||
belongs_to :tax_rate, -> { where spree_adjustments: { originator_type: 'Spree::TaxRate' } },
|
||||
foreign_key: 'originator_id'
|
||||
|
||||
scope :enterprise_fee, -> { where(originator_type: 'EnterpriseFee') }
|
||||
scope :admin, -> { where(source_type: nil, originator_type: nil) }
|
||||
scope :included_tax, -> {
|
||||
where(originator_type: 'Spree::TaxRate', adjustable_type: 'Spree::LineItem')
|
||||
}
|
||||
|
||||
scope :with_tax, -> { where('spree_adjustments.included_tax <> 0') }
|
||||
scope :without_tax, -> { where('spree_adjustments.included_tax = 0') }
|
||||
scope :payment_fee, -> { where(AdjustmentScopes::PAYMENT_FEE_SCOPE) }
|
||||
scope :shipping, -> { where(AdjustmentScopes::SHIPPING_SCOPE) }
|
||||
scope :eligible, -> { where(AdjustmentScopes::ELIGIBLE_SCOPE) }
|
||||
|
||||
localize_number :amount
|
||||
|
||||
def set_included_tax!(rate)
|
||||
tax = amount - (amount / (1 + rate))
|
||||
set_absolute_included_tax! tax
|
||||
end
|
||||
|
||||
def set_absolute_included_tax!(tax)
|
||||
# This rubocop issue can only be fixed when Adjustment#update! is brought from Spree to OFN
|
||||
# and renamed to something else, then AR's update! can be used instead of update_attributes!
|
||||
# rubocop:disable Rails/ActiveRecordAliases
|
||||
update_attributes! included_tax: tax.round(2)
|
||||
# rubocop:enable Rails/ActiveRecordAliases
|
||||
end
|
||||
|
||||
def display_included_tax
|
||||
Spree::Money.new(included_tax, currency: currency)
|
||||
end
|
||||
|
||||
def has_tax?
|
||||
included_tax > 0
|
||||
end
|
||||
|
||||
def self.without_callbacks
|
||||
skip_callback :save, :after, :update_adjustable
|
||||
skip_callback :destroy, :after, :update_adjustable
|
||||
|
||||
result = yield
|
||||
ensure
|
||||
set_callback :save, :after, :update_adjustable
|
||||
set_callback :destroy, :after, :update_adjustable
|
||||
|
||||
result
|
||||
end
|
||||
end
|
||||
end
|
||||
8
app/models/spree/asset.rb
Normal file
8
app/models/spree/asset.rb
Normal file
@@ -0,0 +1,8 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Spree
|
||||
class Asset < ActiveRecord::Base
|
||||
belongs_to :viewable, polymorphic: true, touch: true
|
||||
acts_as_list scope: :viewable
|
||||
end
|
||||
end
|
||||
56
app/models/spree/calculator.rb
Normal file
56
app/models/spree/calculator.rb
Normal file
@@ -0,0 +1,56 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Spree
|
||||
class Calculator < ActiveRecord::Base
|
||||
belongs_to :calculable, polymorphic: true
|
||||
|
||||
# This method must be overriden in concrete calculator.
|
||||
#
|
||||
# It should return amount computed based on #calculable and/or optional parameter
|
||||
def compute(_something = nil)
|
||||
raise NotImplementedError, 'please use concrete calculator'
|
||||
end
|
||||
|
||||
# overwrite to provide description for your calculators
|
||||
def self.description
|
||||
'Base Calculator'
|
||||
end
|
||||
|
||||
###################################################################
|
||||
|
||||
def self.register(*klasses); end
|
||||
|
||||
# Returns all calculators applicable for kind of work
|
||||
def self.calculators
|
||||
Rails.application.config.spree.calculators
|
||||
end
|
||||
|
||||
def to_s
|
||||
self.class.name.titleize.gsub("Calculator\/", "")
|
||||
end
|
||||
|
||||
def description
|
||||
self.class.description
|
||||
end
|
||||
|
||||
def available?(_object)
|
||||
true
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Given an object which might be an Order or a LineItem (amongst
|
||||
# others), return a collection of line items.
|
||||
def line_items_for(object)
|
||||
if object.is_a?(Spree::LineItem)
|
||||
[object]
|
||||
elsif object.respond_to? :line_items
|
||||
object.line_items
|
||||
elsif object.respond_to?(:order) && object.order.present?
|
||||
object.order.line_items
|
||||
else
|
||||
[object]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,19 +0,0 @@
|
||||
module Spree
|
||||
Calculator.class_eval do
|
||||
private
|
||||
|
||||
# Given an object which might be an Order or a LineItem (amongst
|
||||
# others), return a collection of line items.
|
||||
def line_items_for(object)
|
||||
if object.is_a?(Spree::LineItem)
|
||||
[object]
|
||||
elsif object.respond_to? :line_items
|
||||
object.line_items
|
||||
elsif object.respond_to?(:order) && object.order.present?
|
||||
object.order.line_items
|
||||
else
|
||||
[object]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -3,12 +3,14 @@ require 'active_support/concern'
|
||||
# This concern is used to duplicate the associations distributors and distributor_ids
|
||||
# across payment method and gateway
|
||||
# this fixes the inheritance problem https://github.com/openfoodfoundation/openfoodnetwork/issues/2781
|
||||
module Spree::PaymentMethodDistributors
|
||||
extend ActiveSupport::Concern
|
||||
module Spree
|
||||
module PaymentMethodDistributors
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def self.included(base)
|
||||
base.class_eval do
|
||||
has_and_belongs_to_many :distributors, join_table: 'distributors_payment_methods', class_name: 'Enterprise', foreign_key: 'payment_method_id', association_foreign_key: 'distributor_id'
|
||||
def self.included(base)
|
||||
base.class_eval do
|
||||
has_and_belongs_to_many :distributors, join_table: 'distributors_payment_methods', class_name: 'Enterprise', foreign_key: 'payment_method_id', association_foreign_key: 'distributor_id'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
17
app/models/spree/country.rb
Normal file
17
app/models/spree/country.rb
Normal file
@@ -0,0 +1,17 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Spree
|
||||
class Country < ActiveRecord::Base
|
||||
has_many :states, -> { order('name ASC') }
|
||||
|
||||
validates :name, :iso_name, presence: true
|
||||
|
||||
def <=>(other)
|
||||
name <=> other.name
|
||||
end
|
||||
|
||||
def to_s
|
||||
name
|
||||
end
|
||||
end
|
||||
end
|
||||
155
app/models/spree/credit_card.rb
Normal file
155
app/models/spree/credit_card.rb
Normal file
@@ -0,0 +1,155 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Spree
|
||||
class CreditCard < ActiveRecord::Base
|
||||
belongs_to :payment_method
|
||||
belongs_to :user
|
||||
|
||||
has_many :payments, as: :source
|
||||
|
||||
before_save :set_last_digits
|
||||
|
||||
attr_accessor :verification_value
|
||||
attr_reader :number
|
||||
attr_writer :save_requested_by_customer # For holding customer preference in memory
|
||||
|
||||
validates :month, :year, numericality: { only_integer: true }
|
||||
validates :number, presence: true, unless: :has_payment_profile?, on: :create
|
||||
validates :verification_value, presence: true, unless: :has_payment_profile?, on: :create
|
||||
validate :expiry_not_in_the_past
|
||||
|
||||
after_create :ensure_single_default_card
|
||||
after_save :ensure_single_default_card, if: :default_card_needs_updating?
|
||||
|
||||
scope :with_payment_profile, -> { where('gateway_customer_profile_id IS NOT NULL') }
|
||||
|
||||
# needed for some of the ActiveMerchant gateways (eg. SagePay)
|
||||
alias_attribute :brand, :cc_type
|
||||
|
||||
def expiry=(expiry)
|
||||
self[:month], self[:year] = expiry.split(" / ")
|
||||
self[:year] = "20" + self[:year]
|
||||
end
|
||||
|
||||
def number=(num)
|
||||
@number = begin
|
||||
num.gsub(/[^0-9]/, '')
|
||||
rescue StandardError
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
# cc_type is set by jquery.payment, which helpfully provides different
|
||||
# types from Active Merchant. Converting them is necessary.
|
||||
def cc_type=(type)
|
||||
real_type = case type
|
||||
when 'mastercard', 'maestro'
|
||||
'master'
|
||||
when 'amex'
|
||||
'american_express'
|
||||
when 'dinersclub'
|
||||
'diners_club'
|
||||
else
|
||||
type
|
||||
end
|
||||
self[:cc_type] = real_type
|
||||
end
|
||||
|
||||
def set_last_digits
|
||||
number.to_s.gsub!(/\s/, '')
|
||||
verification_value.to_s.gsub!(/\s/, '')
|
||||
self.last_digits ||= number.to_s.length <= 4 ? number : number.to_s.slice(-4..-1)
|
||||
end
|
||||
|
||||
def name?
|
||||
first_name? && last_name?
|
||||
end
|
||||
|
||||
def name
|
||||
"#{first_name} #{last_name}"
|
||||
end
|
||||
|
||||
def verification_value?
|
||||
verification_value.present?
|
||||
end
|
||||
|
||||
# Show the card number, with all but last 4 numbers replace with "X". (XXXX-XXXX-XXXX-4338)
|
||||
def display_number
|
||||
"XXXX-XXXX-XXXX-#{last_digits}"
|
||||
end
|
||||
|
||||
def actions
|
||||
%w{capture void credit}
|
||||
end
|
||||
|
||||
# Indicates whether its possible to capture the payment
|
||||
def can_capture?(payment)
|
||||
payment.pending? || payment.checkout?
|
||||
end
|
||||
|
||||
# Indicates whether its possible to void the payment.
|
||||
def can_void?(payment)
|
||||
!payment.void?
|
||||
end
|
||||
|
||||
# Indicates whether its possible to credit the payment. Note that most gateways require that the
|
||||
# payment be settled first which generally happens within 12-24 hours of the transaction.
|
||||
def can_credit?(payment)
|
||||
return false unless payment.completed?
|
||||
return false unless payment.order.payment_state == 'credit_owed'
|
||||
|
||||
payment.credit_allowed.positive?
|
||||
end
|
||||
|
||||
# Allows us to use a gateway_payment_profile_id to store Stripe Tokens
|
||||
def has_payment_profile?
|
||||
gateway_customer_profile_id.present? || gateway_payment_profile_id.present?
|
||||
end
|
||||
|
||||
def to_active_merchant
|
||||
ActiveMerchant::Billing::CreditCard.new(
|
||||
number: number,
|
||||
month: month,
|
||||
year: year,
|
||||
verification_value: verification_value,
|
||||
first_name: first_name,
|
||||
last_name: last_name
|
||||
)
|
||||
end
|
||||
|
||||
def save_requested_by_customer?
|
||||
!!@save_requested_by_customer
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def expiry_not_in_the_past
|
||||
return unless year.present? && month.present?
|
||||
|
||||
time = "#{year}-#{month}-1".to_time
|
||||
return unless time < Time.zone.now.to_time.beginning_of_month
|
||||
|
||||
errors.add(:base, :card_expired)
|
||||
end
|
||||
|
||||
def reusable?
|
||||
gateway_customer_profile_id.present?
|
||||
end
|
||||
|
||||
def default_missing?
|
||||
!user.credit_cards.exists?(is_default: true)
|
||||
end
|
||||
|
||||
def default_card_needs_updating?
|
||||
is_default_changed? || gateway_customer_profile_id_changed?
|
||||
end
|
||||
|
||||
def ensure_single_default_card
|
||||
return unless user
|
||||
return unless is_default? || (reusable? && default_missing?)
|
||||
|
||||
user.credit_cards.update_all(['is_default=(id=?)', id])
|
||||
self.is_default = true
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,47 +0,0 @@
|
||||
Spree::CreditCard.class_eval do
|
||||
# For holding customer preference in memory
|
||||
attr_writer :save_requested_by_customer
|
||||
|
||||
# Should be able to remove once we reach Spree v2.2.0
|
||||
# https://github.com/spree/spree/commit/411010f3975c919ab298cb63962ee492455b415c
|
||||
belongs_to :payment_method
|
||||
|
||||
belongs_to :user
|
||||
|
||||
after_create :ensure_single_default_card
|
||||
after_save :ensure_single_default_card, if: :default_card_needs_updating?
|
||||
|
||||
# Allows us to use a gateway_payment_profile_id to store Stripe Tokens
|
||||
# Should be able to remove once we reach Spree v2.2.0
|
||||
# Commit: https://github.com/spree/spree/commit/5a4d690ebc64b264bf12904a70187e7a8735ef3f
|
||||
# See also: https://github.com/spree/spree_gateway/issues/111
|
||||
def has_payment_profile? # rubocop:disable Naming/PredicateName
|
||||
gateway_customer_profile_id.present? || gateway_payment_profile_id.present?
|
||||
end
|
||||
|
||||
def save_requested_by_customer?
|
||||
!!@save_requested_by_customer
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def reusable?
|
||||
gateway_customer_profile_id.present?
|
||||
end
|
||||
|
||||
def default_missing?
|
||||
!user.credit_cards.exists?(is_default: true)
|
||||
end
|
||||
|
||||
def default_card_needs_updating?
|
||||
is_default_changed? || gateway_customer_profile_id_changed?
|
||||
end
|
||||
|
||||
def ensure_single_default_card
|
||||
return unless user
|
||||
return unless is_default? || (reusable? && default_missing?)
|
||||
|
||||
user.credit_cards.update_all(['is_default=(id=?)', id])
|
||||
self.is_default = true
|
||||
end
|
||||
end
|
||||
62
app/models/spree/gateway.rb
Normal file
62
app/models/spree/gateway.rb
Normal file
@@ -0,0 +1,62 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spree/concerns/payment_method_distributors'
|
||||
|
||||
module Spree
|
||||
class Gateway < PaymentMethod
|
||||
include Spree::PaymentMethodDistributors
|
||||
|
||||
delegate_belongs_to :provider, :authorize, :purchase, :capture, :void, :credit
|
||||
|
||||
validates :name, :type, presence: true
|
||||
|
||||
# Default to live
|
||||
preference :server, :string, default: 'live'
|
||||
preference :test_mode, :boolean, default: false
|
||||
|
||||
def payment_source_class
|
||||
CreditCard
|
||||
end
|
||||
|
||||
# instantiates the selected gateway and configures with the options stored in the database
|
||||
def self.current
|
||||
super
|
||||
end
|
||||
|
||||
def provider
|
||||
gateway_options = options
|
||||
gateway_options.delete :login if gateway_options.key?(:login) && gateway_options[:login].nil?
|
||||
if gateway_options[:server]
|
||||
ActiveMerchant::Billing::Base.gateway_mode = gateway_options[:server].to_sym
|
||||
end
|
||||
@provider ||= provider_class.new(gateway_options)
|
||||
end
|
||||
|
||||
def options
|
||||
preferences.each_with_object({}){ |(key, value), memo| memo[key.to_sym] = value; }
|
||||
end
|
||||
|
||||
def method_missing(method, *args)
|
||||
if @provider.nil? || !@provider.respond_to?(method)
|
||||
super
|
||||
else
|
||||
provider.__send__(method, *args)
|
||||
end
|
||||
end
|
||||
|
||||
def payment_profiles_supported?
|
||||
false
|
||||
end
|
||||
|
||||
def method_type
|
||||
'gateway'
|
||||
end
|
||||
|
||||
def supports?(source)
|
||||
return true unless provider_class.respond_to? :supports?
|
||||
return false unless source.brand
|
||||
|
||||
provider_class.supports?(source.brand)
|
||||
end
|
||||
end
|
||||
end
|
||||
102
app/models/spree/gateway/bogus.rb
Normal file
102
app/models/spree/gateway/bogus.rb
Normal file
@@ -0,0 +1,102 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Spree
|
||||
class Gateway
|
||||
class Bogus < Spree::Gateway
|
||||
TEST_VISA = ['4111111111111111', '4012888888881881', '4222222222222'].freeze
|
||||
TEST_MC = ['5500000000000004', '5555555555554444', '5105105105105100'].freeze
|
||||
TEST_AMEX = ['378282246310005', '371449635398431',
|
||||
'378734493671000', '340000000000009'].freeze
|
||||
TEST_DISC = ['6011000000000004', '6011111111111117', '6011000990139424'].freeze
|
||||
|
||||
VALID_CCS = ['1', TEST_VISA, TEST_MC, TEST_AMEX, TEST_DISC].flatten
|
||||
|
||||
attr_accessor :test
|
||||
|
||||
def provider_class
|
||||
self.class
|
||||
end
|
||||
|
||||
def preferences
|
||||
{}
|
||||
end
|
||||
|
||||
def create_profile(payment)
|
||||
# simulate the storage of credit card profile using remote service
|
||||
success = VALID_CCS.include? payment.source.number
|
||||
payment.source.update(gateway_customer_profile_id: generate_profile_id(success))
|
||||
end
|
||||
|
||||
def authorize(_money, credit_card, _options = {})
|
||||
profile_id = credit_card.gateway_customer_profile_id
|
||||
if VALID_CCS.include?(credit_card.number) || profile_id&.starts_with?('BGS-')
|
||||
ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {},
|
||||
test: true, authorization: '12345',
|
||||
avs_result: { code: 'A' })
|
||||
else
|
||||
ActiveMerchant::Billing::Response.new(false, 'Bogus Gateway: Forced failure',
|
||||
{ message: 'Bogus Gateway: Forced failure' },
|
||||
test: true)
|
||||
end
|
||||
end
|
||||
|
||||
def purchase(_money, credit_card, _options = {})
|
||||
profile_id = credit_card.gateway_customer_profile_id
|
||||
if VALID_CCS.include?(credit_card.number) || profile_id&.starts_with?('BGS-')
|
||||
ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {},
|
||||
test: true, authorization: '12345',
|
||||
avs_result: { code: 'A' })
|
||||
else
|
||||
ActiveMerchant::Billing::Response.new(false, 'Bogus Gateway: Forced failure',
|
||||
message: 'Bogus Gateway: Forced failure',
|
||||
test: true)
|
||||
end
|
||||
end
|
||||
|
||||
def credit(_money, _credit_card, _response_code, _options = {})
|
||||
ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {},
|
||||
test: true, authorization: '12345')
|
||||
end
|
||||
|
||||
def capture(authorization, _credit_card, _gateway_options)
|
||||
if authorization.response_code == '12345'
|
||||
ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {},
|
||||
test: true, authorization: '67890')
|
||||
else
|
||||
ActiveMerchant::Billing::Response.new(false, 'Bogus Gateway: Forced failure',
|
||||
error: 'Bogus Gateway: Forced failure', test: true)
|
||||
end
|
||||
end
|
||||
|
||||
def void(_response_code, _credit_card, _options = {})
|
||||
ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {},
|
||||
test: true, authorization: '12345')
|
||||
end
|
||||
|
||||
def test?
|
||||
# Test mode is not really relevant with bogus gateway (no such thing as live server)
|
||||
true
|
||||
end
|
||||
|
||||
def payment_profiles_supported?
|
||||
true
|
||||
end
|
||||
|
||||
def actions
|
||||
%w(capture void credit)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def generate_profile_id(success)
|
||||
record = true
|
||||
prefix = success ? 'BGS' : 'FAIL'
|
||||
while record
|
||||
random = "#{prefix}-#{Array.new(6){ rand(6) }.join}"
|
||||
record = CreditCard.find_by(gateway_customer_profile_id: random)
|
||||
end
|
||||
random
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
36
app/models/spree/gateway/bogus_simple.rb
Normal file
36
app/models/spree/gateway/bogus_simple.rb
Normal file
@@ -0,0 +1,36 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Bogus Gateway that doesn't support payment profiles
|
||||
module Spree
|
||||
class Gateway
|
||||
class BogusSimple < Spree::Gateway::Bogus
|
||||
def payment_profiles_supported?
|
||||
false
|
||||
end
|
||||
|
||||
def authorize(_money, credit_card, _options = {})
|
||||
if VALID_CCS.include? credit_card.number
|
||||
ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {},
|
||||
test: true, authorization: '12345',
|
||||
avs_result: { code: 'A' })
|
||||
else
|
||||
ActiveMerchant::Billing::Response.new(false, 'Bogus Gateway: Forced failure',
|
||||
{ message: 'Bogus Gateway: Forced failure' },
|
||||
test: true)
|
||||
end
|
||||
end
|
||||
|
||||
def purchase(_money, credit_card, _options = {})
|
||||
if VALID_CCS.include? credit_card.number
|
||||
ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {},
|
||||
test: true, authorization: '12345',
|
||||
avs_result: { code: 'A' })
|
||||
else
|
||||
ActiveMerchant::Billing::Response.new(false, 'Bogus Gateway: Forced failure',
|
||||
message: 'Bogus Gateway: Forced failure',
|
||||
test: true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,9 +0,0 @@
|
||||
require 'spree/concerns/payment_method_distributors'
|
||||
|
||||
Spree::Gateway.class_eval do
|
||||
include Spree::PaymentMethodDistributors
|
||||
|
||||
# Default to live
|
||||
preference :server, :string, default: 'live'
|
||||
preference :test_mode, :boolean, default: false
|
||||
end
|
||||
76
app/models/spree/image.rb
Normal file
76
app/models/spree/image.rb
Normal file
@@ -0,0 +1,76 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Spree
|
||||
class Image < Asset
|
||||
validates_attachment_presence :attachment
|
||||
validate :no_attachment_errors
|
||||
|
||||
has_attached_file :attachment,
|
||||
styles: { mini: '48x48>', small: '100x100>',
|
||||
product: '240x240>', large: '600x600>' },
|
||||
default_style: :product,
|
||||
url: '/spree/products/:id/:style/:basename.:extension',
|
||||
path: ':rails_root/public/spree/products/:id/:style/:basename.:extension',
|
||||
convert_options: { all: '-strip -auto-orient -colorspace RGB' }
|
||||
|
||||
# save the w,h of the original image (from which others can be calculated)
|
||||
# we need to look at the write-queue for images which have not been saved yet
|
||||
after_post_process :find_dimensions
|
||||
|
||||
include Spree::Core::S3Support
|
||||
supports_s3 :attachment
|
||||
|
||||
Spree::Image.attachment_definitions[:attachment][:styles] =
|
||||
ActiveSupport::JSON.decode(Spree::Config[:attachment_styles]).symbolize_keys!
|
||||
Spree::Image.attachment_definitions[:attachment][:path] = Spree::Config[:attachment_path]
|
||||
Spree::Image.attachment_definitions[:attachment][:url] = Spree::Config[:attachment_url]
|
||||
Spree::Image.attachment_definitions[:attachment][:default_url] =
|
||||
Spree::Config[:attachment_default_url]
|
||||
Spree::Image.attachment_definitions[:attachment][:default_style] =
|
||||
Spree::Config[:attachment_default_style]
|
||||
|
||||
# used by admin products autocomplete
|
||||
def mini_url
|
||||
attachment.url(:mini, false)
|
||||
end
|
||||
|
||||
def find_dimensions
|
||||
temporary = attachment.queued_for_write[:original]
|
||||
filename = temporary.path unless temporary.nil?
|
||||
filename = attachment.path if filename.blank?
|
||||
geometry = Paperclip::Geometry.from_file(filename)
|
||||
self.attachment_width = geometry.width
|
||||
self.attachment_height = geometry.height
|
||||
end
|
||||
|
||||
# if there are errors from the plugin, then add a more meaningful message
|
||||
def no_attachment_errors
|
||||
return if attachment.errors.empty?
|
||||
|
||||
errors.add :attachment, "Paperclip returned errors for file '#{attachment_file_name}' - check ImageMagick installation or image source file."
|
||||
false
|
||||
end
|
||||
|
||||
# Spree stores attachent definitions in JSON. This converts the style name and format to
|
||||
# strings. However, when paperclip encounters these, it doesn't recognise the format.
|
||||
# Here we solve that problem by converting format and style name to symbols.
|
||||
# See also: ImageSettingsController decorator.
|
||||
#
|
||||
# eg. {'mini' => ['48x48>', 'png']} is converted to {mini: ['48x48>', :png]}
|
||||
def self.format_styles(styles)
|
||||
styles_a = styles.map do |name, style|
|
||||
style[1] = style[1].to_sym if style.is_a? Array
|
||||
[name.to_sym, style]
|
||||
end
|
||||
|
||||
Hash[styles_a]
|
||||
end
|
||||
|
||||
def self.reformat_styles
|
||||
Spree::Image.attachment_definitions[:attachment][:styles] =
|
||||
format_styles(Spree::Image.attachment_definitions[:attachment][:styles])
|
||||
end
|
||||
|
||||
reformat_styles
|
||||
end
|
||||
end
|
||||
@@ -1,23 +0,0 @@
|
||||
Spree::Image.class_eval do
|
||||
# Spree stores attachent definitions in JSON. This converts the style name and format to
|
||||
# strings. However, when paperclip encounters these, it doesn't recognise the format.
|
||||
# Here we solve that problem by converting format and style name to symbols.
|
||||
# See also: ImageSettingsController decorator.
|
||||
#
|
||||
# eg. {'mini' => ['48x48>', 'png']} is converted to {mini: ['48x48>', :png]}
|
||||
def self.format_styles(styles)
|
||||
styles_a = styles.map do |name, style|
|
||||
style[1] = style[1].to_sym if style.is_a? Array
|
||||
[name.to_sym, style]
|
||||
end
|
||||
|
||||
Hash[styles_a]
|
||||
end
|
||||
|
||||
def self.reformat_styles
|
||||
Spree::Image.attachment_definitions[:attachment][:styles] =
|
||||
format_styles(Spree::Image.attachment_definitions[:attachment][:styles])
|
||||
end
|
||||
|
||||
reformat_styles
|
||||
end
|
||||
@@ -179,11 +179,11 @@ module Spree
|
||||
# For more information, please see Spree::Payment#set_unique_identifier
|
||||
order_id: gateway_order_id }
|
||||
|
||||
options.merge!({ shipping: order.ship_total * 100,
|
||||
tax: order.tax_total * 100,
|
||||
subtotal: order.item_total * 100,
|
||||
discount: order.promo_total * 100,
|
||||
currency: currency })
|
||||
options.merge!(shipping: order.ship_total * 100,
|
||||
tax: order.tax_total * 100,
|
||||
subtotal: order.item_total * 100,
|
||||
discount: 0,
|
||||
currency: currency)
|
||||
|
||||
options.merge!({ billing_address: order.bill_address.try(:active_merchant_hash),
|
||||
shipping_address: order.ship_address.try(:active_merchant_hash) })
|
||||
|
||||
137
app/models/spree/payment_method.rb
Normal file
137
app/models/spree/payment_method.rb
Normal file
@@ -0,0 +1,137 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spree/concerns/payment_method_distributors'
|
||||
|
||||
module Spree
|
||||
class PaymentMethod < ActiveRecord::Base
|
||||
include Spree::Core::CalculatedAdjustments
|
||||
include Spree::PaymentMethodDistributors
|
||||
|
||||
acts_as_taggable
|
||||
acts_as_paranoid
|
||||
|
||||
DISPLAY = [:both, :front_end, :back_end].freeze
|
||||
default_scope -> { where(deleted_at: nil) }
|
||||
|
||||
has_many :credit_cards, class_name: "Spree::CreditCard"
|
||||
|
||||
validates :name, presence: true
|
||||
validate :distributor_validation
|
||||
|
||||
after_initialize :init
|
||||
|
||||
scope :production, -> { where(environment: 'production') }
|
||||
|
||||
scope :managed_by, lambda { |user|
|
||||
if user.has_spree_role?('admin')
|
||||
where(nil)
|
||||
else
|
||||
joins(:distributors).
|
||||
where('distributors_payment_methods.distributor_id IN (?)',
|
||||
user.enterprises.select(&:id)).
|
||||
select('DISTINCT spree_payment_methods.*')
|
||||
end
|
||||
}
|
||||
|
||||
scope :for_distributors, ->(distributors) {
|
||||
non_unique_matches = unscoped.joins(:distributors).where(enterprises: { id: distributors })
|
||||
where(id: non_unique_matches.map(&:id))
|
||||
}
|
||||
|
||||
scope :for_distributor, lambda { |distributor|
|
||||
joins(:distributors).
|
||||
where('enterprises.id = ?', distributor)
|
||||
}
|
||||
|
||||
scope :for_subscriptions, -> { where(type: Subscription::ALLOWED_PAYMENT_METHOD_TYPES) }
|
||||
|
||||
scope :by_name, -> { order('spree_payment_methods.name ASC') }
|
||||
|
||||
scope :available, lambda { |display_on = 'both'|
|
||||
where(active: true).
|
||||
where('spree_payment_methods.display_on=? OR spree_payment_methods.display_on=? OR spree_payment_methods.display_on IS NULL', display_on, '').
|
||||
where('spree_payment_methods.environment=? OR spree_payment_methods.environment=? OR spree_payment_methods.environment IS NULL', Rails.env, '')
|
||||
}
|
||||
|
||||
def self.providers
|
||||
Rails.application.config.spree.payment_methods
|
||||
end
|
||||
|
||||
def provider_class
|
||||
raise 'You must implement provider_class method for this gateway.'
|
||||
end
|
||||
|
||||
# The class that will process payments for this payment type, used for @payment.source
|
||||
# e.g. CreditCard in the case of a the Gateway payment type
|
||||
# nil means the payment method doesn't require a source e.g. check
|
||||
def payment_source_class
|
||||
raise 'You must implement payment_source_class method for this gateway.'
|
||||
end
|
||||
|
||||
def self.active?
|
||||
where(type: to_s, environment: Rails.env, active: true).count.positive?
|
||||
end
|
||||
|
||||
def method_type
|
||||
type.demodulize.downcase
|
||||
end
|
||||
|
||||
def self.find_with_destroyed(*args)
|
||||
unscoped { find(*args) }
|
||||
end
|
||||
|
||||
def payment_profiles_supported?
|
||||
false
|
||||
end
|
||||
|
||||
def source_required?
|
||||
true
|
||||
end
|
||||
|
||||
def auto_capture?
|
||||
Spree::Config[:auto_capture]
|
||||
end
|
||||
|
||||
def supports?(_source)
|
||||
true
|
||||
end
|
||||
|
||||
def init
|
||||
unless reflections.key?(:calculator)
|
||||
self.class.include Spree::Core::CalculatedAdjustments
|
||||
end
|
||||
|
||||
self.calculator ||= Calculator::FlatRate.new(preferred_amount: 0)
|
||||
end
|
||||
|
||||
def has_distributor?(distributor)
|
||||
distributors.include?(distributor)
|
||||
end
|
||||
|
||||
def self.clean_name
|
||||
case name
|
||||
when "Spree::PaymentMethod::Check"
|
||||
"Cash/EFT/etc. (payments for which automatic validation is not required)"
|
||||
when "Spree::Gateway::Migs"
|
||||
"MasterCard Internet Gateway Service (MIGS)"
|
||||
when "Spree::Gateway::Pin"
|
||||
"Pin Payments"
|
||||
when "Spree::Gateway::StripeConnect"
|
||||
"Stripe"
|
||||
when "Spree::Gateway::StripeSCA"
|
||||
"Stripe SCA"
|
||||
when "Spree::Gateway::PayPalExpress"
|
||||
"PayPal Express"
|
||||
else
|
||||
i = name.rindex('::') + 2
|
||||
name[i..-1]
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def distributor_validation
|
||||
validates_with DistributorsValidator
|
||||
end
|
||||
end
|
||||
end
|
||||
33
app/models/spree/payment_method/check.rb
Normal file
33
app/models/spree/payment_method/check.rb
Normal file
@@ -0,0 +1,33 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Spree
|
||||
class PaymentMethod
|
||||
class Check < Spree::PaymentMethod
|
||||
def actions
|
||||
%w{capture void}
|
||||
end
|
||||
|
||||
# Indicates whether its possible to capture the payment
|
||||
def can_capture?(payment)
|
||||
['checkout', 'pending'].include?(payment.state)
|
||||
end
|
||||
|
||||
# Indicates whether its possible to void the payment.
|
||||
def can_void?(payment)
|
||||
payment.state != 'void'
|
||||
end
|
||||
|
||||
def capture(*_args)
|
||||
ActiveMerchant::Billing::Response.new(true, "", {}, {})
|
||||
end
|
||||
|
||||
def void(*_args)
|
||||
ActiveMerchant::Billing::Response.new(true, "", {}, {})
|
||||
end
|
||||
|
||||
def source_required?
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,84 +0,0 @@
|
||||
require 'spree/concerns/payment_method_distributors'
|
||||
|
||||
Spree::PaymentMethod.class_eval do
|
||||
include Spree::Core::CalculatedAdjustments
|
||||
include Spree::PaymentMethodDistributors
|
||||
|
||||
acts_as_taggable
|
||||
|
||||
has_many :credit_cards, class_name: "Spree::CreditCard" # from Spree v.2.3.0 d470b31798f37
|
||||
|
||||
after_initialize :init
|
||||
|
||||
validate :distributor_validation
|
||||
|
||||
# -- Scopes
|
||||
scope :managed_by, lambda { |user|
|
||||
if user.has_spree_role?('admin')
|
||||
where(nil)
|
||||
else
|
||||
joins(:distributors).
|
||||
where('distributors_payment_methods.distributor_id IN (?)', user.enterprises.select(&:id)).
|
||||
select('DISTINCT spree_payment_methods.*')
|
||||
end
|
||||
}
|
||||
|
||||
scope :for_distributors, ->(distributors) {
|
||||
non_unique_matches = unscoped.joins(:distributors).where(enterprises: { id: distributors })
|
||||
where(id: non_unique_matches.map(&:id))
|
||||
}
|
||||
|
||||
scope :for_distributor, lambda { |distributor|
|
||||
joins(:distributors).
|
||||
where('enterprises.id = ?', distributor)
|
||||
}
|
||||
|
||||
scope :for_subscriptions, -> { where(type: Subscription::ALLOWED_PAYMENT_METHOD_TYPES) }
|
||||
|
||||
scope :by_name, -> { order('spree_payment_methods.name ASC') }
|
||||
|
||||
# Rewrite Spree's ruby-land class method as a scope
|
||||
scope :available, lambda { |display_on = 'both'|
|
||||
where(active: true).
|
||||
where('spree_payment_methods.display_on=? OR spree_payment_methods.display_on=? OR spree_payment_methods.display_on IS NULL', display_on, '').
|
||||
where('spree_payment_methods.environment=? OR spree_payment_methods.environment=? OR spree_payment_methods.environment IS NULL', Rails.env, '')
|
||||
}
|
||||
|
||||
def init
|
||||
unless reflections.key?(:calculator)
|
||||
self.class.include Spree::Core::CalculatedAdjustments
|
||||
end
|
||||
|
||||
self.calculator ||= Calculator::FlatRate.new(preferred_amount: 0)
|
||||
end
|
||||
|
||||
def has_distributor?(distributor)
|
||||
distributors.include?(distributor)
|
||||
end
|
||||
|
||||
def self.clean_name
|
||||
case name
|
||||
when "Spree::PaymentMethod::Check"
|
||||
"Cash/EFT/etc. (payments for which automatic validation is not required)"
|
||||
when "Spree::Gateway::Migs"
|
||||
"MasterCard Internet Gateway Service (MIGS)"
|
||||
when "Spree::Gateway::Pin"
|
||||
"Pin Payments"
|
||||
when "Spree::Gateway::StripeConnect"
|
||||
"Stripe"
|
||||
when "Spree::Gateway::StripeSCA"
|
||||
"Stripe SCA"
|
||||
when "Spree::Gateway::PayPalExpress"
|
||||
"PayPal Express"
|
||||
else
|
||||
i = name.rindex('::') + 2
|
||||
name[i..-1]
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def distributor_validation
|
||||
validates_with DistributorsValidator
|
||||
end
|
||||
end
|
||||
@@ -1,45 +1,47 @@
|
||||
module Spree::Preferences
|
||||
class FileConfiguration < Configuration
|
||||
def self.preference(name, type, *args)
|
||||
if type == :file
|
||||
super "#{name}_file_name", :string, *args
|
||||
super "#{name}_content_type", :string, *args
|
||||
super "#{name}_file_size", :integer, *args
|
||||
super "#{name}_updated_at", :string, *args
|
||||
module Spree
|
||||
module Preferences
|
||||
class FileConfiguration < Configuration
|
||||
def self.preference(name, type, *args)
|
||||
if type == :file
|
||||
super "#{name}_file_name", :string, *args
|
||||
super "#{name}_content_type", :string, *args
|
||||
super "#{name}_file_size", :integer, *args
|
||||
super "#{name}_updated_at", :string, *args
|
||||
|
||||
else
|
||||
super name, type, *args
|
||||
else
|
||||
super name, type, *args
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def get_preference(key)
|
||||
if !has_preference?(key) && has_attachment?(key)
|
||||
public_send key
|
||||
else
|
||||
super key
|
||||
def get_preference(key)
|
||||
if !has_preference?(key) && has_attachment?(key)
|
||||
public_send key
|
||||
else
|
||||
super key
|
||||
end
|
||||
end
|
||||
end
|
||||
alias :[] :get_preference
|
||||
alias :[] :get_preference
|
||||
|
||||
def preference_type(name)
|
||||
if has_attachment? name
|
||||
:file
|
||||
else
|
||||
super name
|
||||
def preference_type(name)
|
||||
if has_attachment? name
|
||||
:file
|
||||
else
|
||||
super name
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Spree's Configuration responds to preference methods via method_missing, but doesn't
|
||||
# override respond_to?, which consequently reports those methods as unavailable. Paperclip
|
||||
# errors if respond_to? isn't correct, so we override it here.
|
||||
def respond_to?(method, include_all = false)
|
||||
name = method.to_s.delete('=')
|
||||
super(self.class.preference_getter_method(name), include_all) || super(method, include_all)
|
||||
end
|
||||
# Spree's Configuration responds to preference methods via method_missing, but doesn't
|
||||
# override respond_to?, which consequently reports those methods as unavailable. Paperclip
|
||||
# errors if respond_to? isn't correct, so we override it here.
|
||||
def respond_to?(method, include_all = false)
|
||||
name = method.to_s.delete('=')
|
||||
super(self.class.preference_getter_method(name), include_all) || super(method, include_all)
|
||||
end
|
||||
|
||||
def has_attachment?(name)
|
||||
self.class.respond_to?(:attachment_definitions) &&
|
||||
self.class.attachment_definitions.key?(name.to_sym)
|
||||
def has_attachment?(name)
|
||||
self.class.respond_to?(:attachment_definitions) &&
|
||||
self.class.attachment_definitions.key?(name.to_sym)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
21
app/models/spree/state.rb
Normal file
21
app/models/spree/state.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Spree
|
||||
class State < ActiveRecord::Base
|
||||
belongs_to :country, class_name: 'Spree::Country'
|
||||
|
||||
validates :country, :name, presence: true
|
||||
|
||||
def self.find_all_by_name_or_abbr(name_or_abbr)
|
||||
where('name = ? OR abbr = ?', name_or_abbr, name_or_abbr)
|
||||
end
|
||||
|
||||
def <=>(other)
|
||||
name <=> other.name
|
||||
end
|
||||
|
||||
def to_s
|
||||
name
|
||||
end
|
||||
end
|
||||
end
|
||||
60
app/models/spree/stock_location.rb
Normal file
60
app/models/spree/stock_location.rb
Normal file
@@ -0,0 +1,60 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Spree
|
||||
class StockLocation < ActiveRecord::Base
|
||||
has_many :stock_items, dependent: :delete_all
|
||||
has_many :stock_movements, through: :stock_items
|
||||
|
||||
belongs_to :state, class_name: 'Spree::State'
|
||||
belongs_to :country, class_name: 'Spree::Country'
|
||||
|
||||
validates :name, presence: true
|
||||
|
||||
scope :active, -> { where(active: true) }
|
||||
|
||||
after_create :create_stock_items
|
||||
|
||||
# Wrapper for creating a new stock item respecting the backorderable config
|
||||
def propagate_variant(variant)
|
||||
stock_items.create!(variant: variant, backorderable: backorderable_default)
|
||||
end
|
||||
|
||||
def stock_item(variant)
|
||||
stock_items.where(variant_id: variant).order(:id).first
|
||||
end
|
||||
|
||||
def stock_item_or_create(variant)
|
||||
stock_item(variant) || stock_items.create(variant: variant)
|
||||
end
|
||||
|
||||
def count_on_hand(variant)
|
||||
stock_item(variant).try(:count_on_hand)
|
||||
end
|
||||
|
||||
def backorderable?(variant)
|
||||
stock_item(variant).try(:backorderable?)
|
||||
end
|
||||
|
||||
def restock(variant, quantity, originator = nil)
|
||||
move(variant, quantity, originator)
|
||||
end
|
||||
|
||||
def unstock(variant, quantity, originator = nil)
|
||||
move(variant, -quantity, originator)
|
||||
end
|
||||
|
||||
def move(variant, quantity, originator = nil)
|
||||
variant.move(quantity, originator)
|
||||
end
|
||||
|
||||
def fill_status(variant, quantity)
|
||||
variant.fill_status(quantity)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_stock_items
|
||||
Variant.find_each { |variant| propagate_variant(variant) }
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,9 +0,0 @@
|
||||
Spree::StockLocation.class_eval do
|
||||
def move(variant, quantity, originator = nil)
|
||||
variant.move(quantity, originator)
|
||||
end
|
||||
|
||||
def fill_status(variant, quantity)
|
||||
variant.fill_status(quantity)
|
||||
end
|
||||
end
|
||||
25
app/models/spree/stock_movement.rb
Normal file
25
app/models/spree/stock_movement.rb
Normal file
@@ -0,0 +1,25 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Spree
|
||||
class StockMovement < ActiveRecord::Base
|
||||
belongs_to :stock_item, class_name: 'Spree::StockItem'
|
||||
belongs_to :originator, polymorphic: true
|
||||
|
||||
after_create :update_stock_item_quantity
|
||||
|
||||
validates :stock_item, presence: true
|
||||
validates :quantity, presence: true
|
||||
|
||||
scope :recent, -> { order('created_at DESC') }
|
||||
|
||||
def readonly?
|
||||
!new_record?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def update_stock_item_quantity
|
||||
stock_item.adjust_count_on_hand quantity
|
||||
end
|
||||
end
|
||||
end
|
||||
20
app/models/spree/tax_category.rb
Normal file
20
app/models/spree/tax_category.rb
Normal file
@@ -0,0 +1,20 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Spree
|
||||
class TaxCategory < ActiveRecord::Base
|
||||
acts_as_paranoid
|
||||
validates :name, presence: true, uniqueness: { scope: :deleted_at }
|
||||
|
||||
has_many :tax_rates, dependent: :destroy
|
||||
|
||||
before_save :set_default_category
|
||||
|
||||
def set_default_category
|
||||
# set existing default tax category to false if this one has been marked as default
|
||||
|
||||
return unless is_default && tax_category = self.class.find_by(is_default: true)
|
||||
|
||||
tax_category.update_column(:is_default, false) unless tax_category == self
|
||||
end
|
||||
end
|
||||
end
|
||||
132
app/models/spree/tax_rate.rb
Normal file
132
app/models/spree/tax_rate.rb
Normal file
@@ -0,0 +1,132 @@
|
||||
# frozen_string_literal: false
|
||||
|
||||
module Spree
|
||||
class DefaultTaxZoneValidator < ActiveModel::Validator
|
||||
def validate(record)
|
||||
return unless record.included_in_price
|
||||
|
||||
return if Zone.default_tax
|
||||
|
||||
record.errors.add(:included_in_price, Spree.t(:included_price_validation))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module Spree
|
||||
class TaxRate < ActiveRecord::Base
|
||||
acts_as_paranoid
|
||||
include Spree::Core::CalculatedAdjustments
|
||||
belongs_to :zone, class_name: "Spree::Zone"
|
||||
belongs_to :tax_category, class_name: "Spree::TaxCategory"
|
||||
|
||||
validates :amount, presence: true, numericality: true
|
||||
validates :tax_category_id, presence: true
|
||||
validates_with DefaultTaxZoneValidator
|
||||
|
||||
scope :by_zone, ->(zone) { where(zone_id: zone) }
|
||||
|
||||
# Gets the array of TaxRates appropriate for the specified order
|
||||
def self.match(order)
|
||||
return [] if order.distributor && !order.distributor.charges_sales_tax
|
||||
return [] unless order.tax_zone
|
||||
|
||||
all.select do |rate|
|
||||
rate.zone == order.tax_zone || rate.zone.contains?(order.tax_zone) || rate.zone.default_tax
|
||||
end
|
||||
end
|
||||
|
||||
def self.adjust(order)
|
||||
order.adjustments.tax.destroy_all
|
||||
order.line_item_adjustments.where(originator_type: 'Spree::TaxRate').destroy_all
|
||||
|
||||
match(order).each do |rate|
|
||||
rate.adjust(order)
|
||||
end
|
||||
end
|
||||
|
||||
# For VAT, the default rate is the rate that is configured for the default category
|
||||
# It is needed for every price calculation (as all customer facing prices include VAT)
|
||||
# Here we return the actual amount, which may be 0 in case of wrong setup, but is never nil
|
||||
def self.default
|
||||
category = TaxCategory.includes(:tax_rates).find_by(is_default: true)
|
||||
return 0 unless category
|
||||
|
||||
address ||= Address.new(country_id: Spree::Config[:default_country_id])
|
||||
rate = category.tax_rates.detect { |tax_rate| tax_rate.zone.include? address }.try(:amount)
|
||||
|
||||
rate || 0
|
||||
end
|
||||
|
||||
# Creates necessary tax adjustments for the order.
|
||||
def adjust(order)
|
||||
label = create_label
|
||||
if included_in_price
|
||||
if Zone.default_tax.contains? order.tax_zone
|
||||
order.line_items.each { |line_item| create_adjustment(label, line_item, line_item) }
|
||||
else
|
||||
amount = -1 * calculator.compute(order)
|
||||
label = Spree.t(:refund) + label
|
||||
|
||||
order.adjustments.create(
|
||||
amount: amount,
|
||||
source: order,
|
||||
originator: self,
|
||||
state: "closed",
|
||||
label: label
|
||||
)
|
||||
end
|
||||
else
|
||||
create_adjustment(label, order, order)
|
||||
end
|
||||
|
||||
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|
|
||||
adjustment.set_absolute_included_tax! adjustment.amount
|
||||
end
|
||||
end
|
||||
|
||||
# Manually apply a TaxRate to a particular amount. TaxRates normally compute against
|
||||
# LineItems or Orders, so we mock out a line item here to fit the interface
|
||||
# that our calculator (usually DefaultTax) expects.
|
||||
def compute_tax(amount)
|
||||
line_item = LineItem.new quantity: 1
|
||||
line_item.tax_category = tax_category
|
||||
line_item.define_singleton_method(:price) { amount }
|
||||
|
||||
# Tax on adjustments (represented by the included_tax field) is always inclusive of
|
||||
# tax. However, there's nothing to stop an admin from setting one up with a tax rate
|
||||
# that's marked as not inclusive of tax, and that would result in the DefaultTax
|
||||
# calculator generating a slightly incorrect value. Therefore, we treat the tax
|
||||
# rate as inclusive of tax for the calculations below, regardless of its original
|
||||
# setting.
|
||||
with_tax_included_in_price do
|
||||
calculator.compute line_item
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_label
|
||||
label = ""
|
||||
label << (name.presence || tax_category.name) + " "
|
||||
label << (show_rate_in_label? ? "#{amount * 100}%" : "")
|
||||
end
|
||||
|
||||
def with_tax_included_in_price
|
||||
old_included_in_price = included_in_price
|
||||
|
||||
self.included_in_price = true
|
||||
calculator.calculable.included_in_price = true
|
||||
|
||||
result = yield
|
||||
ensure
|
||||
self.included_in_price = old_included_in_price
|
||||
calculator.calculable.included_in_price = old_included_in_price
|
||||
|
||||
result
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,61 +0,0 @@
|
||||
module Spree
|
||||
TaxRate.class_eval do
|
||||
class << self
|
||||
def match(order)
|
||||
return [] if order.distributor && !order.distributor.charges_sales_tax
|
||||
return [] unless order.tax_zone
|
||||
|
||||
all.select do |rate|
|
||||
rate.zone == order.tax_zone || rate.zone.contains?(order.tax_zone) || rate.zone.default_tax
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def adjust_with_included_tax(order)
|
||||
adjust_without_included_tax(order)
|
||||
|
||||
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|
|
||||
adjustment.set_absolute_included_tax! adjustment.amount
|
||||
end
|
||||
end
|
||||
alias_method_chain :adjust, :included_tax
|
||||
|
||||
# Manually apply a TaxRate to a particular amount. TaxRates normally compute against
|
||||
# LineItems or Orders, so we mock out a line item here to fit the interface
|
||||
# that our calculator (usually DefaultTax) expects.
|
||||
def compute_tax(amount)
|
||||
line_item = LineItem.new quantity: 1
|
||||
line_item.tax_category = tax_category
|
||||
line_item.define_singleton_method(:price) { amount }
|
||||
|
||||
# Tax on adjustments (represented by the included_tax field) is always inclusive of
|
||||
# tax. However, there's nothing to stop an admin from setting one up with a tax rate
|
||||
# that's marked as not inclusive of tax, and that would result in the DefaultTax
|
||||
# calculator generating a slightly incorrect value. Therefore, we treat the tax
|
||||
# rate as inclusive of tax for the calculations below, regardless of its original
|
||||
# setting.
|
||||
with_tax_included_in_price do
|
||||
calculator.compute line_item
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def with_tax_included_in_price
|
||||
old_included_in_price = included_in_price
|
||||
|
||||
self.included_in_price = true
|
||||
calculator.calculable.included_in_price = true
|
||||
|
||||
result = yield
|
||||
ensure
|
||||
self.included_in_price = old_included_in_price
|
||||
calculator.calculable.included_in_price = old_included_in_price
|
||||
|
||||
result
|
||||
end
|
||||
end
|
||||
end
|
||||
144
app/models/spree/zone.rb
Normal file
144
app/models/spree/zone.rb
Normal file
@@ -0,0 +1,144 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Spree
|
||||
class Zone < ActiveRecord::Base
|
||||
has_many :zone_members, dependent: :destroy, class_name: "Spree::ZoneMember"
|
||||
has_many :tax_rates, dependent: :destroy
|
||||
has_and_belongs_to_many :shipping_methods, join_table: 'spree_shipping_methods_zones'
|
||||
|
||||
validates :name, presence: true, uniqueness: true
|
||||
after_save :remove_defunct_members
|
||||
after_save :remove_previous_default
|
||||
|
||||
alias :members :zone_members
|
||||
accepts_nested_attributes_for :zone_members, allow_destroy: true,
|
||||
reject_if: proc { |a| a['zoneable_id'].blank? }
|
||||
|
||||
def kind
|
||||
return unless members.any? && members.none? { |member| member.try(:zoneable_type).nil? }
|
||||
|
||||
members.last.zoneable_type.demodulize.underscore
|
||||
end
|
||||
|
||||
def kind=(value)
|
||||
# do nothing - just here to satisfy the form
|
||||
end
|
||||
|
||||
def include?(address)
|
||||
return false unless address
|
||||
|
||||
members.any? do |zone_member|
|
||||
case zone_member.zoneable_type
|
||||
when 'Spree::Country'
|
||||
zone_member.zoneable_id == address.country_id
|
||||
when 'Spree::State'
|
||||
zone_member.zoneable_id == address.state_id
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Returns the matching zone with the highest priority zone type (State, Country, Zone.)
|
||||
# Returns nil in the case of no matches.
|
||||
def self.match(address)
|
||||
return unless matches = includes(:zone_members).
|
||||
order('zone_members_count', 'created_at').
|
||||
select { |zone| zone.include? address }
|
||||
|
||||
['state', 'country'].each do |zone_kind|
|
||||
if match = matches.detect { |zone| zone_kind == zone.kind }
|
||||
return match
|
||||
end
|
||||
end
|
||||
matches.first
|
||||
end
|
||||
|
||||
# convenience method for returning the countries contained within a zone
|
||||
def countries
|
||||
@countries ||= case kind
|
||||
when 'country' then zoneables
|
||||
when 'state' then zoneables.collect(&:country)
|
||||
end.flatten.compact.uniq
|
||||
end
|
||||
|
||||
def <=>(other)
|
||||
name <=> other.name
|
||||
end
|
||||
|
||||
# All zoneables belonging to the zone members. Will be a collection of either
|
||||
# countries or states depending on the zone type.
|
||||
def zoneables
|
||||
members.collect(&:zoneable)
|
||||
end
|
||||
|
||||
def country_ids
|
||||
if kind == 'country'
|
||||
members.collect(&:zoneable_id)
|
||||
else
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
def state_ids
|
||||
if kind == 'state'
|
||||
members.collect(&:zoneable_id)
|
||||
else
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
def country_ids=(ids)
|
||||
zone_members.destroy_all
|
||||
ids.reject(&:blank?).map do |id|
|
||||
member = ZoneMember.new
|
||||
member.zoneable_type = 'Spree::Country'
|
||||
member.zoneable_id = id
|
||||
members << member
|
||||
end
|
||||
end
|
||||
|
||||
def state_ids=(ids)
|
||||
zone_members.destroy_all
|
||||
ids.reject(&:blank?).map do |id|
|
||||
member = ZoneMember.new
|
||||
member.zoneable_type = 'Spree::State'
|
||||
member.zoneable_id = id
|
||||
members << member
|
||||
end
|
||||
end
|
||||
|
||||
def self.default_tax
|
||||
find_by(default_tax: true)
|
||||
end
|
||||
|
||||
# Indicates whether the specified zone falls entirely within the zone performing
|
||||
# the check.
|
||||
def contains?(target)
|
||||
return false if kind == 'state' && target.kind == 'country'
|
||||
return false if zone_members.empty? || target.zone_members.empty?
|
||||
|
||||
if kind == target.kind
|
||||
if target.zoneables.any? { |target_zoneable| zoneables.exclude?(target_zoneable) }
|
||||
return false
|
||||
end
|
||||
elsif target.zoneables.any? { |target_state| zoneables.exclude?(target_state.country) }
|
||||
return false
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def remove_defunct_members
|
||||
return unless zone_members.any?
|
||||
|
||||
zone_members.where('zoneable_id IS NULL OR zoneable_type != ?',
|
||||
"Spree::#{kind.capitalize}").destroy_all
|
||||
end
|
||||
|
||||
def remove_previous_default
|
||||
Spree::Zone.where('id != ?', id).update_all(default_tax: false) if default_tax
|
||||
end
|
||||
end
|
||||
end
|
||||
14
app/models/spree/zone_member.rb
Normal file
14
app/models/spree/zone_member.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Spree
|
||||
class ZoneMember < ActiveRecord::Base
|
||||
belongs_to :zone, class_name: 'Spree::Zone', counter_cache: true
|
||||
belongs_to :zoneable, polymorphic: true
|
||||
|
||||
def name
|
||||
return nil if zoneable.nil?
|
||||
|
||||
zoneable.name
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -4,8 +4,8 @@ class Api::Admin::EnterpriseSerializer < ActiveModel::Serializer
|
||||
:preferred_shopfront_message, :preferred_shopfront_closed_message,
|
||||
:preferred_shopfront_taxon_order, :preferred_shopfront_order_cycle_order,
|
||||
:preferred_product_selection_from_inventory_only,
|
||||
:owner, :contact, :users, :tag_groups, :default_tag_group,
|
||||
:require_login, :allow_guest_orders, :allow_order_changes,
|
||||
:preferred_show_customer_names_to_suppliers, :owner, :contact, :users, :tag_groups,
|
||||
:default_tag_group, :require_login, :allow_guest_orders, :allow_order_changes,
|
||||
:logo, :promo_image
|
||||
|
||||
has_one :owner, serializer: Api::Admin::UserSerializer
|
||||
|
||||
@@ -17,7 +17,7 @@ module Api
|
||||
end
|
||||
|
||||
def open_street_map_provider_options
|
||||
ContentConfig.open_street_map_provider_options.to_json
|
||||
ContentConfig.open_street_map_provider_options
|
||||
end
|
||||
|
||||
def open_street_map_default_latitude
|
||||
|
||||
35
app/services/order_data_masker.rb
Normal file
35
app/services/order_data_masker.rb
Normal file
@@ -0,0 +1,35 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class OrderDataMasker
|
||||
def initialize(order)
|
||||
@order = order
|
||||
end
|
||||
|
||||
def call
|
||||
mask_customer_names unless customer_names_allowed?
|
||||
mask_contact_data
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_accessor :order
|
||||
|
||||
def customer_names_allowed?
|
||||
order.distributor.preferences[:show_customer_names_to_suppliers]
|
||||
end
|
||||
|
||||
def mask_customer_names
|
||||
order.bill_address&.assign_attributes(firstname: I18n.t('admin.reports.hidden'),
|
||||
lastname: "")
|
||||
order.ship_address&.assign_attributes(firstname: I18n.t('admin.reports.hidden'),
|
||||
lastname: "")
|
||||
end
|
||||
|
||||
def mask_contact_data
|
||||
order.bill_address&.assign_attributes(phone: "", address1: "", address2: "",
|
||||
city: "", zipcode: "", state: nil)
|
||||
order.ship_address&.assign_attributes(phone: "", address1: "", address2: "",
|
||||
city: "", zipcode: "", state: nil)
|
||||
order.assign_attributes(email: I18n.t('admin.reports.hidden'))
|
||||
end
|
||||
end
|
||||
@@ -30,7 +30,7 @@ module PermittedAttributes
|
||||
:abn, :acn, :charges_sales_tax, :display_invoice_logo, :invoice_text,
|
||||
:preferred_product_selection_from_inventory_only, :preferred_shopfront_message,
|
||||
:preferred_shopfront_closed_message, :preferred_shopfront_taxon_order,
|
||||
:preferred_shopfront_order_cycle_order
|
||||
:preferred_shopfront_order_cycle_order, :preferred_show_customer_names_to_suppliers
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
@@ -89,3 +89,16 @@
|
||||
.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
|
||||
|
||||
@@ -38,9 +38,12 @@
|
||||
%loading
|
||||
|
||||
= render "layouts/bugsnag_js"
|
||||
%script{:src => "https://js.stripe.com/v3/", :type => "text/javascript"}
|
||||
|
||||
- if Spree::Config.stripe_connect_enabled
|
||||
%script{:src => "https://js.stripe.com/v3/", :type => "text/javascript"}
|
||||
- if !ContentConfig.open_street_map_enabled
|
||||
%script{src: "//maps.googleapis.com/maps/api/js?libraries=places,geometry#{ ENV['GOOGLE_MAPS_API_KEY'] ? '&key=' + ENV['GOOGLE_MAPS_API_KEY'] : ''} "}
|
||||
|
||||
= javascript_include_tag "darkswarm/all"
|
||||
= javascript_include_tag "web/all"
|
||||
= render "layouts/i18n_script"
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
- content_for :page_actions do
|
||||
%li= button_link_to t(:new_adjustment), new_admin_order_adjustment_url(@order), :icon => 'icon-plus'
|
||||
= render partial: 'spree/admin/shared/order_links'
|
||||
%li= button_link_to t(:back_to_orders_list), admin_orders_path, :icon => 'icon-arrow-left'
|
||||
|
||||
= render :partial => 'adjustments_table'
|
||||
|
||||
@@ -151,7 +151,7 @@
|
||||
%th.final_weight_volume{ 'ng-show' => 'columns.final_weight_volume.visible' }
|
||||
= t("admin.orders.bulk_management.weight_volume")
|
||||
%th.price{ 'ng-show' => 'columns.price.visible' }
|
||||
= t("admin.price (#{currency_symbol})")
|
||||
= "#{t('admin.price')} (#{currency_symbol})"
|
||||
%th.actions
|
||||
%th.actions
|
||||
= t("admin.orders.bulk_management.ask")
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
= Spree.t(:customer_details)
|
||||
|
||||
- content_for :page_actions do
|
||||
= render partial: 'spree/admin/shared/order_links'
|
||||
%li= button_link_to Spree.t(:back_to_orders_list), admin_orders_path, :icon => 'icon-arrow-left'
|
||||
|
||||
- if @order.cart? || @order.address?
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
- content_for :page_actions do
|
||||
- if can?(:fire, @order)
|
||||
%li= event_links
|
||||
- if can?(:resend, @order)
|
||||
%li= button_link_to Spree.t(:resend), resend_admin_order_url(@order), :method => :post, :icon => 'icon-email'
|
||||
%li.links-dropdown#links-dropdown{ links: order_links(@order).to_json }
|
||||
= render partial: 'spree/admin/shared/order_links'
|
||||
- if can?(:admin, Spree::Order)
|
||||
%li= button_link_to t(:back_to_orders_list), admin_orders_path, :icon => 'icon-arrow-left'
|
||||
|
||||
@@ -29,6 +27,3 @@
|
||||
|
||||
%div{"data-hook" => "admin_order_edit_form"}
|
||||
= render :partial => 'form', :locals => { :order => @order }
|
||||
|
||||
:coffee
|
||||
angular.bootstrap(document.getElementById("links-dropdown"),['admin.dropdown'])
|
||||
|
||||
@@ -70,4 +70,4 @@
|
||||
%p
|
||||
= @order.distributor.invoice_text
|
||||
|
||||
= render 'spree/order_mailer/payment'
|
||||
= render 'spree/shared/payment'
|
||||
|
||||
@@ -71,4 +71,4 @@
|
||||
%p
|
||||
= @order.distributor.invoice_text
|
||||
|
||||
= render 'spree/order_mailer/payment'
|
||||
= render 'spree/shared/payment'
|
||||
|
||||
@@ -37,13 +37,10 @@
|
||||
.alpha.seven.columns.dashboard_item.single-ent#map
|
||||
.header
|
||||
%h3
|
||||
%span.icon-map-marker
|
||||
%span.icon-user
|
||||
= t "your_profil_live"
|
||||
%p
|
||||
= t "on_ofn_map"
|
||||
.list
|
||||
/-# Can we pass an anchor here to zoom to our enterprise?
|
||||
%a.button.bottom{href: main_app.map_path, target: '_blank'}
|
||||
%a.button.bottom{href: main_app.enterprise_shop_url(@enterprise), target: '_blank'}
|
||||
= t "see"
|
||||
= @enterprise.name
|
||||
= t "live"
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
- if @order.outstanding_balance?
|
||||
%li#new_payment_section
|
||||
= button_link_to t(:new_payment), new_admin_order_payment_url(@order), icon: 'icon-plus'
|
||||
= render partial: 'spree/admin/shared/order_links'
|
||||
%li= button_link_to t(:back_to_orders_list), admin_orders_path, icon: 'icon-arrow-left'
|
||||
|
||||
- content_for :page_title do
|
||||
@@ -13,7 +14,7 @@
|
||||
|
||||
- if @order.outstanding_balance?
|
||||
%h5.outstanding-balance
|
||||
= @order.outstanding_balance < 0 ? t(:credit_owed) : t(:balance_due)
|
||||
= outstanding_balance_label(@order)
|
||||
\:
|
||||
%strong= @order.display_outstanding_balance
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
%p.customer-names-tip
|
||||
= t(".customer_names_tip")
|
||||
@@ -6,4 +6,6 @@
|
||||
%br
|
||||
= button t(:search)
|
||||
|
||||
= render partial: "customer_names_message"
|
||||
|
||||
= render "table", id: "listing_orders", msg_option: t(:search)
|
||||
|
||||
@@ -25,4 +25,6 @@
|
||||
.row
|
||||
= button t(:search)
|
||||
|
||||
= render partial: "customer_names_message"
|
||||
|
||||
= render "table", id: "listing_orders", msg_option: t(:search)
|
||||
|
||||
@@ -25,4 +25,6 @@
|
||||
.row
|
||||
= button t(:search)
|
||||
|
||||
= render partial: "customer_names_message"
|
||||
|
||||
= render "table", id: "listing_orders", msg_option: t(:search)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
- if @order.shipments.any? &:shipped?
|
||||
%li
|
||||
= button_link_to t('.new_return_authorization'), new_admin_order_return_authorization_url(@order), icon: 'icon-plus'
|
||||
= render partial: 'spree/admin/shared/order_links'
|
||||
%li= button_link_to t('.back_to_orders_list'), spree.admin_orders_path, icon: 'icon-arrow-left'
|
||||
|
||||
- content_for :page_title do
|
||||
|
||||
4
app/views/spree/admin/shared/_order_links.html.haml
Normal file
4
app/views/spree/admin/shared/_order_links.html.haml
Normal file
@@ -0,0 +1,4 @@
|
||||
%li.links-dropdown#links-dropdown{ links: order_links(@order).to_json }
|
||||
|
||||
:coffee
|
||||
angular.bootstrap(document.getElementById("links-dropdown"),['admin.dropdown'])
|
||||
@@ -1,14 +0,0 @@
|
||||
%p.callout
|
||||
%span{:style => "float:right;"}
|
||||
- if @order.paid?
|
||||
= t :email_payment_paid
|
||||
- else
|
||||
= t :email_payment_not_paid
|
||||
%strong
|
||||
= t :email_payment_summary
|
||||
%h4
|
||||
= t :email_payment_method
|
||||
%strong= last_payment_method(@order)&.name
|
||||
%p
|
||||
%em= last_payment_method(@order)&.description
|
||||
%p
|
||||
@@ -21,7 +21,7 @@
|
||||
= t :email_confirm_customer_details_html, distributor: @order.distributor.name
|
||||
|
||||
= render 'order_summary'
|
||||
= render 'payment'
|
||||
= render 'spree/shared/payment'
|
||||
= render 'shipping'
|
||||
= render 'special_instructions'
|
||||
= render 'signoff'
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
= @order.bill_address.phone if @order.bill_address.phone
|
||||
|
||||
= render 'order_summary'
|
||||
= render 'payment'
|
||||
= render 'spree/shared/payment'
|
||||
= render 'shipping'
|
||||
= render 'special_instructions'
|
||||
|
||||
|
||||
15
app/views/spree/shared/_payment.html.haml
Normal file
15
app/views/spree/shared/_payment.html.haml
Normal file
@@ -0,0 +1,15 @@
|
||||
%p.callout
|
||||
%span{:style => "float:right;"}
|
||||
- if @order.outstanding_balance?
|
||||
= outstanding_balance_label(@order)
|
||||
\:
|
||||
%strong= @order.display_outstanding_balance
|
||||
- else
|
||||
- if @order.paid?
|
||||
= t :email_payment_paid
|
||||
- else
|
||||
= t :email_payment_not_paid
|
||||
%strong
|
||||
= t :email_payment_summary
|
||||
- if @order.payments.any?
|
||||
= render partial: 'spree/shared/payments_list', locals: { payments: @order.payments }
|
||||
14
app/views/spree/shared/_payments_list.html.haml
Normal file
14
app/views/spree/shared/_payments_list.html.haml
Normal file
@@ -0,0 +1,14 @@
|
||||
%table.payments-list
|
||||
%thead
|
||||
%tr
|
||||
%th= t('.date_time')
|
||||
%th= t('.payment_method')
|
||||
%th.payment-state= t('.payment_state')
|
||||
%th.amount= t('.amount')
|
||||
%tbody
|
||||
- payments.each do |payment|
|
||||
%tr
|
||||
%td= l(payment.created_at, format: "%b %d, %Y %H:%M")
|
||||
%td.payment-method-name= payment_method_name(payment)
|
||||
%td.payment-state.payment-state-value= t(payment.state, scope: :payment_states, default: payment.state.capitalize)
|
||||
%td.amount= payment.display_amount.to_html
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
= render 'spree/order_mailer/order_summary'
|
||||
|
||||
= render 'spree/order_mailer/payment'
|
||||
= render 'spree/shared/payment'
|
||||
= render 'spree/order_mailer/shipping'
|
||||
= render 'spree/order_mailer/special_instructions'
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
= render 'spree/order_mailer/order_summary'
|
||||
|
||||
= render 'spree/order_mailer/payment'
|
||||
= render 'spree/shared/payment'
|
||||
= render 'spree/order_mailer/shipping'
|
||||
= render 'spree/order_mailer/special_instructions'
|
||||
|
||||
|
||||
@@ -18,11 +18,6 @@ module Openfoodnetwork
|
||||
Dir.glob(File.join(File.dirname(__FILE__), "../app/**/*_decorator*.rb")) do |c|
|
||||
Rails.configuration.cache_classes ? require(c) : load(c)
|
||||
end
|
||||
|
||||
# Load application's view overrides
|
||||
Dir.glob(File.join(File.dirname(__FILE__), "../app/overrides/*.rb")) do |c|
|
||||
Rails.configuration.cache_classes ? require(c) : load(c)
|
||||
end
|
||||
end
|
||||
|
||||
# Settings dependent on locale
|
||||
|
||||
@@ -18,9 +18,6 @@ Spree::Gateway.class_eval do
|
||||
acts_as_taggable
|
||||
end
|
||||
|
||||
require "#{Rails.root}/app/models/spree/payment_method_decorator"
|
||||
require "#{Rails.root}/app/models/spree/gateway_decorator"
|
||||
|
||||
Spree.config do |config|
|
||||
config.shipping_instructions = true
|
||||
config.address_requires_state = true
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
ar:
|
||||
language_name: "الانجيلزي"
|
||||
language_name: "العربي"
|
||||
activerecord:
|
||||
attributes:
|
||||
enterprise_fee:
|
||||
@@ -14,6 +14,7 @@ ar:
|
||||
spree/payment:
|
||||
amount: القيمة
|
||||
state: ولاية
|
||||
source: المصدر
|
||||
spree/product:
|
||||
primary_taxon: "نوع المنتج "
|
||||
supplier: "المورد"
|
||||
@@ -34,6 +35,10 @@ ar:
|
||||
taken: "يوجد حساب متصل بهذا الايميل.\nالرجاء الدخول او اعادة تعيين كلمة السر."
|
||||
spree/order:
|
||||
no_card: لا يوجد بطاقة ائتمان معتمدة متاحة لاتمام عملية الدفع
|
||||
spree/credit_card:
|
||||
attributes:
|
||||
base:
|
||||
card_expired: "انتهت صلاحيته"
|
||||
order_cycle:
|
||||
attributes:
|
||||
orders_close_at:
|
||||
@@ -179,6 +184,7 @@ ar:
|
||||
explainer: فشلت المعالجة التلقائية لهذه الطلبات لسبب غير معروف. لا ينبغي أن يحدث هذا ، يرجى الاتصال بنا إذا كنت ترى هذا.
|
||||
home: "OFN"
|
||||
title: "شبكة الغذاء المفتوح"
|
||||
welcome_to: "مرحبا بك في"
|
||||
site_meta_description: "نبدأ من الألف إلى الياء. مع المزارعين والمزارعين على استعداد لرواية قصصهم بفخر وحق. مع الموزعين على استعداد لتوصيل الأشخاص بالمنتجات بطريقة عادلة وبصدق. مع المشترين الذين يعتقدون أن أفضل قرارات التسوق الأسبوعية يمكن ..."
|
||||
search_by_name: البحث بالاسم أو الضاحية ...
|
||||
producers_join: المنتجون الأستراليون مدعوون الآن للانضمام إلى شبكة الغذاء المفتوح.
|
||||
@@ -221,6 +227,7 @@ ar:
|
||||
enterprises: المؤسسات
|
||||
enterprise_groups: مجموعات
|
||||
reports: التقارير
|
||||
listing_reports: قائمة التقارير
|
||||
variant_overrides: المخزون
|
||||
import: استيراد
|
||||
spree_products: منتجات Spree
|
||||
@@ -267,6 +274,9 @@ ar:
|
||||
on hand: "متوفر"
|
||||
ship: "الشحن"
|
||||
shipping_category: "نوع الشحن"
|
||||
height: "الارتفاع"
|
||||
width: "العرض"
|
||||
depth: "العمق"
|
||||
actions:
|
||||
create_and_add_another: "إنشاء وإضافة آخر"
|
||||
create: "انشاء"
|
||||
@@ -322,6 +332,7 @@ ar:
|
||||
show_n_more: عرض %{num} أكثر
|
||||
choose: "أختر..."
|
||||
please_select: الرجاء اختيار ...
|
||||
column_save_as_default: إحفظ كافتراض اساسي
|
||||
columns: أعمدة
|
||||
actions: أجراءات
|
||||
viewing: "عرض: %{current_view_name}"
|
||||
@@ -366,7 +377,10 @@ ar:
|
||||
title: "إعدادات Matomo"
|
||||
matomo_url: "العنوان الالكتروني ل Matomo "
|
||||
matomo_site_id: "معرف موقع Matomo"
|
||||
matomo_tag_manager_url: "عنوان URL لبرنامج Matomo "
|
||||
info_html: "ماتومو هو تطبيق تحليلات الويب والجوال. يمكنك اضافة Matomo محليًا أو استخدام خدمة مستضافة على السحابة. انظر <a href='http://matomo.org' target='_blank'>matomo.org</a> لمزيد من المعلومات."
|
||||
config_instructions_html: "هنا يمكنك تهيئة تكامل Matomo لشبكة الغذاء المفتوح. يجب أن يشير عنوان الالكتروني URL الخاص بـ Matomo أدناه إلى مثيل Matomo حيث سيتم إرسال معلومات تتبع المستخدم إلى ؛ إذا تم تركه فارغًا ، فسيتم تعطيل تتبع مستخدم Matomo. حقل معرف الموقع ليس إلزاميًا ولكنه مفيد إذا كنت تتعقب أكثر من موقع ويب على مثيل Matomo ؛ يمكن العثور عليه على وحدة تحكم مثيل Matomo."
|
||||
config_instructions_tag_manager_html: "يؤدي تعيين عنوان URL لبرنامج Matomo إلى تمكين Matomo . تتيح لك هذه الأداة إعداد أحداث التحليلات. يتم نسخ عنوان URL لبرنامج Matomo من قسم كود التثبيت في Manager. تأكد من تحديد الحاوية والبيئة المناسبة لأن هذه الخيارات تغير عنوان URL."
|
||||
customers:
|
||||
index:
|
||||
new_customer: "عميل جديد"
|
||||
@@ -472,6 +486,7 @@ ar:
|
||||
line_number: "السطر %{number}:"
|
||||
encoding_error: "يرجى التحقق من إعداد اللغة للملف المصدر والتأكد من حفظه بترميز UTF-8"
|
||||
unexpected_error: "واجه استيراد المنتج خطأ غير متوقع أثناء فتح الملف: %{error_message}"
|
||||
malformed_csv: "صادف استيراد المنتج ملف CSV مشوه: %{error_message}"
|
||||
index:
|
||||
notice: "تنويه"
|
||||
beta_notice: "لا تزال هذه الميزة تجريبية: قد تواجه بعض الأخطاء أثناء استخدامها. من فضلك لا تتردد في الاتصال بالدعم."
|
||||
@@ -684,6 +699,7 @@ ar:
|
||||
ofn_uid_tip: المعرف الفريد المستخدم لتحديد الشركة على شبكة الغذاء المفتوح.
|
||||
shipping_methods:
|
||||
name: "اسم"
|
||||
applies: "نشيط؟"
|
||||
manage: "إدارة طرق الشحن"
|
||||
create_button: "إنشاء طريقة شحن جديدة"
|
||||
create_one_button: "إنشاء واحدة الآن"
|
||||
@@ -706,6 +722,10 @@ ar:
|
||||
enable_subscriptions_tip: "تمكين الاشتراكات وظيفيا ؟"
|
||||
enable_subscriptions_false: "تعليق"
|
||||
enable_subscriptions_true: "تمكين"
|
||||
customer_names_in_reports: "أسماء العملاء في التقارير"
|
||||
customer_names_tip: "قم بتمكين مورديك من رؤية أسماء عملائك في التقارير"
|
||||
customer_names_false: "تعليق"
|
||||
customer_names_true: "تمكين"
|
||||
shopfront_message: "رسالة واجهة المتجر"
|
||||
shopfront_message_placeholder: >
|
||||
رسالة اختيارية للترحيب بالعملاء وشرح كيفية التسوق معك. إذا تم إدخال
|
||||
@@ -861,6 +881,7 @@ ar:
|
||||
incoming: "الوارد"
|
||||
supplier: "المورد"
|
||||
products: "منتجات"
|
||||
receival_details: "تفاصيل الاستلام"
|
||||
fees: "رسوم"
|
||||
save: "حفظ"
|
||||
save_and_next: "حفظ والتالي"
|
||||
@@ -872,6 +893,7 @@ ar:
|
||||
distributor: "الموزع"
|
||||
products: "منتجات"
|
||||
tags: "الاوسمة"
|
||||
delivery_details: "تفاصيل التسليم"
|
||||
fees: "رسوم"
|
||||
previous: "السابق"
|
||||
save: "حفظ"
|
||||
@@ -968,7 +990,7 @@ ar:
|
||||
resend_email: إعادة إرسال البريد الإلكتروني
|
||||
has_no_payment_methods: "لا تحتوي %{enterprise} حاليًا على طريقة دفع"
|
||||
has_no_shipping_methods: "%{enterprise} لا يوجد لديها حاليا طريقة شحن"
|
||||
email_confirmation: "تأكيد البريد الإلكتروني معلق. لقد أرسلنا رسالة تأكيد بالبريد الإلكتروني إلى %{email}."
|
||||
email_confirmation: "تأكيد البريد الإلكتروني معلق. لقد أرسلنا لك رسالة تأكيد على البريد الإلكتروني إلى %{email}."
|
||||
not_visible: "%{enterprise} غير مرئي وبالتالي لا يمكن العثور عليه على الخريطة أو في عمليات البحث"
|
||||
reports:
|
||||
hidden: خفية
|
||||
@@ -1034,7 +1056,7 @@ ar:
|
||||
unpause_subscription: إلغاء الاشتراك المؤقت
|
||||
cancel_subscription: إلغاء الاشتراك
|
||||
filters:
|
||||
query_placeholder: "البحث عن طريق البريد الإلكتروني ..."
|
||||
query_placeholder: "ابحث عن طريق البريد الإلكتروني ..."
|
||||
setup_explanation:
|
||||
title: "الاشتراكات"
|
||||
just_a_few_more_steps: 'فقط بضع خطوات أخرى قبل أن تبدأ:'
|
||||
@@ -1143,7 +1165,12 @@ ar:
|
||||
cart: "سلة"
|
||||
cart_sidebar:
|
||||
checkout: "تابع للخروج"
|
||||
edit_cart: "تعديل سلة التسوق"
|
||||
items_in_cart_singular: "%{num} عنصر في سلة التسوق الخاصة بك"
|
||||
items_in_cart_plural: "%{num} العناصر في سلة التسوق الخاصة بك"
|
||||
close: "إغلاق"
|
||||
cart_empty: "سلة التسوق فارغة"
|
||||
take_me_shopping: "خذني للتسوق!"
|
||||
signed_in:
|
||||
profile: "الملف الشخصي"
|
||||
mobile_menu:
|
||||
@@ -1155,7 +1182,7 @@ ar:
|
||||
footer_secure: "آمن وموثوق به."
|
||||
footer_secure_text: "تستخدم شبكة الغذاء المفتوح تشفير( SSL 2048 بت RSA) في كل مكان للحفاظ على خصوصية معلومات التسوق والدفع. لا تقوم خوادمنا بتخزين تفاصيل بطاقة الائتمان الخاصة بك ، وتتم معالجة المدفوعات بواسطة خدمات متوافقة مع PCI."
|
||||
footer_contact_headline: "أبق على اتصال"
|
||||
footer_contact_email: "ارسل لنا عبر البريد الإلكتروني"
|
||||
footer_contact_email: "راسلنا عبر البريد الإلكتروني"
|
||||
footer_nav_headline: "التنقل"
|
||||
footer_join_headline: "انضم إلينا"
|
||||
footer_join_body: "إنشاء قائمة أو متجر أو دليل المجموعة على شبكة الغذاء المفتوح."
|
||||
@@ -1175,7 +1202,11 @@ ar:
|
||||
signup: "سجل"
|
||||
contact: "اتصل"
|
||||
require_customer_login: "يمكن للعملاء المعتمدين فقط الوصول إلى هذا المتجر."
|
||||
require_login_html: "إذا كنت عميلاً معتمدًا بالفعل ، %{login} أو %{signup} للمتابعة."
|
||||
require_login_2_html: "تريد أن تبدأ التسوق هنا؟ من فضلك %{contact} %{enterprise} واسأل عن الانضمام."
|
||||
require_customer_html: "إذا كنت ترغب في بدء التسوق هنا ، فيرجى %{contact} %{enterprise} أن تسأل عن الانضمام."
|
||||
select_oc:
|
||||
select_oc_html: "يرجى <span class='highlighted'>اختيار الوقت الذي تريده لطلبك</span> ، لمعرفة المنتجات المتوفرة."
|
||||
card_could_not_be_updated: لا يمكن تحديث البطاقة
|
||||
card_could_not_be_saved: لا يمكن حفظ البطاقة
|
||||
spree_gateway_error_flash_for_checkout: "حدثت مشكلة في معلومات الدفع الخاصة بك: %{error}"
|
||||
@@ -1204,13 +1235,13 @@ ar:
|
||||
ticket_column_unit_price: "سعر الوحدة"
|
||||
ticket_column_total_price: "السعر الكلي"
|
||||
menu_1_title: "محلات"
|
||||
menu_1_url: "/محلات"
|
||||
menu_1_url: "/shops"
|
||||
menu_2_title: "خريطة"
|
||||
menu_2_url: "/خريطة"
|
||||
menu_2_url: "/map"
|
||||
menu_3_title: "المنتجين"
|
||||
menu_3_url: "/ المنتجين"
|
||||
menu_3_url: "/producers"
|
||||
menu_4_title: "مجموعات"
|
||||
menu_4_url: "/مجموعات"
|
||||
menu_4_url: "/groups"
|
||||
menu_5_title: "حول"
|
||||
menu_5_url: "https://about.openfoodnetwork.org.au/"
|
||||
menu_6_title: "الاتصال"
|
||||
@@ -1541,12 +1572,17 @@ ar:
|
||||
orders_changeable_orders_alert_html: تم تأكيد هذا الطلب ، ولكن يمكنك إجراء تغييرات حتى <strong>%{oc_close}</strong> .
|
||||
products_clear: ازالة
|
||||
products_showing: "عرض:"
|
||||
products_results_for: "نتائج"
|
||||
products_or: "أو"
|
||||
products_and: "و"
|
||||
products_filters_in: "في"
|
||||
products_with: مع
|
||||
products_search: "بحث..."
|
||||
products_filter_by: "مرشح بواسطة"
|
||||
products_filter_selected: "تم الاختيار"
|
||||
products_filter_heading: "المرشحات"
|
||||
products_filter_clear: "ازالة"
|
||||
products_filter_done: "تم"
|
||||
products_loading: "جارٍ تحميل المنتجات ..."
|
||||
products_updating_cart: "جارٍ تحديث سلة المشتريات..."
|
||||
products_cart_empty: "السلة فارغة"
|
||||
@@ -1557,6 +1593,8 @@ ar:
|
||||
products_update_error_msg: "فشل الحفظ."
|
||||
products_update_error_data: "فشل الحفظ بسبب بيانات غير صالحة:"
|
||||
products_changes_saved: "تم حفظ التغييرات."
|
||||
products_no_results_html: "عذرا ، لم يتم العثور على نتائج لـ %{query}"
|
||||
products_clear_search: "مسح البحث"
|
||||
search_no_results_html: "عذرًا ، لم يتم العثور على نتائج لـ %{query}. جرب بحث آخر؟"
|
||||
components_profiles_popover: "لا تملك ملفات التعريف واجهة متجر على شبكة الغذاء المفتوح ، ولكن قد يكون لها متجر على ارض الواقع أو عبر الإنترنت في أي مكان آخر"
|
||||
components_profiles_show: "إظهار الملفات الشخصية"
|
||||
@@ -1701,6 +1739,7 @@ ar:
|
||||
remember_me: تذكرنى
|
||||
are_you_sure: "هل أنت واثق؟"
|
||||
orders_open: "الطلب مفتوح"
|
||||
closing: "إغلاق"
|
||||
going_back_to_home_page: "الرجوع إلى الصفحة الرئيسية"
|
||||
creating: انشاء
|
||||
updating: تحديث
|
||||
@@ -1915,6 +1954,7 @@ ar:
|
||||
admin_enterprise_relationships_permits: "تسمح"
|
||||
admin_enterprise_relationships_seach_placeholder: "بحث"
|
||||
admin_enterprise_relationships_button_create: "انشاء"
|
||||
admin_enterprise_relationships_to: "إلى"
|
||||
admin_enterprise_groups: "مجموعات المؤسسة"
|
||||
admin_enterprise_groups_name: "اسم"
|
||||
admin_enterprise_groups_owner: "المالك"
|
||||
@@ -1943,6 +1983,7 @@ ar:
|
||||
supplier: "المورد"
|
||||
product_name: "اسم المنتج"
|
||||
product_description: "وصف المنتج"
|
||||
permalink: "الرابط الثابت"
|
||||
shipping_categories: "فئات الشحن"
|
||||
units: "حجم الوحدة"
|
||||
coordinator: "منسق"
|
||||
@@ -2023,7 +2064,6 @@ ar:
|
||||
spree_user_enterprise_limit_error: "^ %{email} غير مسموح به لامتلاك أي مؤسسات أخرى (الحد الأقصى هو %{enterprise_limit})."
|
||||
spree_variant_product_error: يجب أن يكون لديك نوع واحد على الأقل
|
||||
your_profil_live: "ملفك الشخصي نشط"
|
||||
on_ofn_map: "على خريطة شبكة الغذاء المفتوح"
|
||||
see: "نرى"
|
||||
live: "نشط"
|
||||
manage: "يدير"
|
||||
@@ -2040,6 +2080,7 @@ ar:
|
||||
remove_tax: "إزالة الضريبة"
|
||||
first_name_begins_with: "الاسم الأول يبدأ بـ"
|
||||
last_name_begins_with: "اسم العائلة يبدأ بـ"
|
||||
shipping_method: "طريقة الشحن"
|
||||
new_order: "طلب جديد"
|
||||
enterprise_tos_link: "شروط المؤسسة لخدمة الرابط"
|
||||
enterprise_tos_message: "نريد العمل مع أشخاص يشاركوننا أهدافنا وقيمنا. على هذا النحو ، نطلب من المؤسسات الجديدة الموافقة على"
|
||||
@@ -2059,6 +2100,7 @@ ar:
|
||||
hub_sidebar_at_least: "يجب تحديد مركز واحد على الأقل"
|
||||
hub_sidebar_blue: "أزرق"
|
||||
hub_sidebar_red: "أحمر"
|
||||
order_cycles_closed_for_hub: "المحور الذي حددته مغلق مؤقتًا للطلبات. الرجاء معاودة المحاولة في وقت لاحق."
|
||||
report_customers_distributor: "الموزع"
|
||||
report_customers_supplier: "المورد"
|
||||
report_customers_cycle: "ترتيب الدورة"
|
||||
@@ -2293,6 +2335,7 @@ ar:
|
||||
order_cycles_email_to_producers_notice: 'رسائل البريد الإلكتروني المراد إرسالها إلى المنتجين تم وضعها في قائمة الانتظار للإرسال.'
|
||||
order_cycles_no_permission_to_coordinate_error: "لا تملك أي من مؤسساتك إذنًا لتنسيق دورة الطلب"
|
||||
order_cycles_no_permission_to_create_error: "ليس لديك إذن لإنشاء دورة طلب تنسقها تلك المؤسسة"
|
||||
order_cycle_closed: "تم إغلاق دورة الطلب التي حددتها للتو. حاول مرة اخرى!"
|
||||
back_to_orders_list: "العودة إلى قائمة الطلب"
|
||||
no_orders_found: "لم يتم العثور على أية طلبات"
|
||||
order_information: "معلومات الطلب"
|
||||
@@ -2320,6 +2363,10 @@ ar:
|
||||
resolve_errors: يرجى حل الأخطاء التالية
|
||||
more_items: "+ %{count} ايضا"
|
||||
default_card_updated: تم تحديث البطاقة الافتراضية
|
||||
cart:
|
||||
add_to_cart_failed: >
|
||||
حدثت مشكلة أثناء إضافة هذا المنتج إلى عربة التسوق. ربما أصبح غير متوفر أو
|
||||
أن المحل يغلق.
|
||||
admin:
|
||||
enterprise_limit_reached: "لقد وصلت إلى الحد القياسي للمؤسسات لكل حساب. اكتب %{contact_email} إذا كنت بحاجة إلى زيادته."
|
||||
modals:
|
||||
@@ -2604,6 +2651,13 @@ ar:
|
||||
few: "كل"
|
||||
many: "كل"
|
||||
other: "كل"
|
||||
bunch:
|
||||
zero: "عناقيد"
|
||||
one: "حفنة"
|
||||
two: "عناقيد"
|
||||
few: "عناقيد"
|
||||
many: "عناقيد"
|
||||
other: "عناقيد"
|
||||
pack:
|
||||
zero: "حزم"
|
||||
one: "رزمة"
|
||||
@@ -2611,6 +2665,13 @@ ar:
|
||||
few: "حزم"
|
||||
many: "حزم"
|
||||
other: "حزم"
|
||||
box:
|
||||
zero: "مربعات"
|
||||
one: "صندوق"
|
||||
two: "مربعات"
|
||||
few: "مربعات"
|
||||
many: "مربعات"
|
||||
other: "بكسات"
|
||||
bottle:
|
||||
zero: "زجاجات"
|
||||
one: "زجاجة"
|
||||
@@ -2618,6 +2679,62 @@ ar:
|
||||
few: "زجاجات"
|
||||
many: "زجاجات"
|
||||
other: "زجاجات"
|
||||
jar:
|
||||
zero: "الجرار"
|
||||
one: "إناء"
|
||||
two: "الجرار"
|
||||
few: "الجرار"
|
||||
many: "الجرار"
|
||||
other: "مرتبان"
|
||||
head:
|
||||
zero: "رؤساء"
|
||||
one: "رئيس"
|
||||
two: "رؤساء"
|
||||
few: "رؤساء"
|
||||
many: "رؤساء"
|
||||
other: "رؤوس"
|
||||
bag:
|
||||
zero: "أكياس"
|
||||
one: "كيس"
|
||||
two: "أكياس"
|
||||
few: "أكياس"
|
||||
many: "أكياس"
|
||||
other: "أكياس"
|
||||
loaf:
|
||||
zero: "أرغفة"
|
||||
one: "رغيف"
|
||||
two: "أرغفة"
|
||||
few: "أرغفة"
|
||||
many: "أرغفة"
|
||||
other: "أرغفة"
|
||||
single:
|
||||
zero: "الفردي"
|
||||
one: "غير مرتبطة"
|
||||
two: "الفردي"
|
||||
few: "الفردي"
|
||||
many: "الفردي"
|
||||
other: "الفردي"
|
||||
tub:
|
||||
zero: "أحواض"
|
||||
one: "حوض"
|
||||
two: "أحواض"
|
||||
few: "أحواض"
|
||||
many: "أحواض"
|
||||
other: "أحواض"
|
||||
punnet:
|
||||
zero: "سلات"
|
||||
one: "إناء"
|
||||
two: "سلات"
|
||||
few: "سلات"
|
||||
many: "سلات"
|
||||
other: "سلات"
|
||||
packet:
|
||||
zero: "الحزم"
|
||||
one: "رزمة"
|
||||
two: "الحزم"
|
||||
few: "الحزم"
|
||||
many: "الحزم"
|
||||
other: "الحزم"
|
||||
item:
|
||||
zero: "العناصر"
|
||||
one: "بند"
|
||||
@@ -2639,6 +2756,62 @@ ar:
|
||||
few: "الوحدات"
|
||||
many: "الوحدات"
|
||||
other: "الوحدات"
|
||||
serve:
|
||||
zero: "يخدم"
|
||||
one: "تخدم"
|
||||
two: "يخدم"
|
||||
few: "يخدم"
|
||||
many: "يخدم"
|
||||
other: "خدمة"
|
||||
tray:
|
||||
zero: "صواني"
|
||||
one: "صينية"
|
||||
two: "صواني"
|
||||
few: "صواني"
|
||||
many: "صواني"
|
||||
other: "صواني"
|
||||
piece:
|
||||
zero: "قطع"
|
||||
one: "قطعة"
|
||||
two: "قطع"
|
||||
few: "قطع"
|
||||
many: "قطع"
|
||||
other: "قطع"
|
||||
pot:
|
||||
zero: "الأواني"
|
||||
one: "وعاء"
|
||||
two: "الأواني"
|
||||
few: "الأواني"
|
||||
many: "الأواني"
|
||||
other: "اصص"
|
||||
bundle:
|
||||
zero: "حزم"
|
||||
one: "حزمة"
|
||||
two: "حزم"
|
||||
few: "حزم"
|
||||
many: "حزم"
|
||||
other: "حزم"
|
||||
flask:
|
||||
zero: "قوارير"
|
||||
one: "قارورة"
|
||||
two: "قوارير"
|
||||
few: "قوارير"
|
||||
many: "قوارير"
|
||||
other: "قوارير"
|
||||
basket:
|
||||
zero: "سلال"
|
||||
one: "سلة"
|
||||
two: "سلال"
|
||||
few: "سلال"
|
||||
many: "سلال"
|
||||
other: "سلال"
|
||||
sack:
|
||||
zero: "أكياس"
|
||||
one: "كيس"
|
||||
two: "أكياس"
|
||||
few: "أكياس"
|
||||
many: "أكياس"
|
||||
other: "أكياس"
|
||||
producers:
|
||||
signup:
|
||||
start_free_profile: "ابدأ بملف تعريف مجاني ، وتوسع عندما تكون جاهزًا!"
|
||||
@@ -2696,6 +2869,8 @@ ar:
|
||||
adjustments: "التعديلات"
|
||||
payments: "المدفوعات"
|
||||
return_authorizations: "عودة التراخيص"
|
||||
credit_owed: "الائتمان مدين"
|
||||
new_adjustment: "تعديل جديد"
|
||||
payment: "دفعة"
|
||||
payment_method: "طريقة الدفع او السداد"
|
||||
shipment: "الشحنة"
|
||||
@@ -2768,6 +2943,12 @@ ar:
|
||||
void: "فارغ"
|
||||
login: "تسجيل الدخول"
|
||||
password: "كلمه السر"
|
||||
signature: "التوقيع"
|
||||
solution: "المحاليل"
|
||||
landing_page: "الصفحة المقصودة"
|
||||
server: "الخادم"
|
||||
test_mode: "وضع الاختبار"
|
||||
logourl: "وحدة"
|
||||
configurations: "تهيئة"
|
||||
general_settings: "الاعدادات العامة"
|
||||
site_name: "اسم الموقع"
|
||||
@@ -2884,6 +3065,21 @@ ar:
|
||||
options: "خيارات"
|
||||
actions:
|
||||
update: "تحديث"
|
||||
shared:
|
||||
error_messages:
|
||||
errors_prohibited_this_record_from_being_saved:
|
||||
zero: "منعت أخطاء %{count} حفظ هذا السجل:"
|
||||
one: "حظر خطأ واحد حفظ هذا السجل:"
|
||||
two: "منعت أخطاء %{count} حفظ هذا السجل:"
|
||||
few: "منعت أخطاء %{count} حفظ هذا السجل:"
|
||||
many: "منعت أخطاء %{count} حفظ هذا السجل:"
|
||||
other: "منعت أخطاء %{count} حفظ هذا السجل:"
|
||||
there_were_problems_with_the_following_fields: "كانت هناك مشاكل مع الحقول التالية"
|
||||
payments_list:
|
||||
date_time: "التاريخ / الوقت"
|
||||
amount: "القيمة"
|
||||
payment_method: "طريقة الدفع او السداد"
|
||||
payment_state: "حالة الدفعة"
|
||||
errors:
|
||||
messages:
|
||||
blank: "لا يمكن أن تكون فارغة"
|
||||
@@ -3026,6 +3222,8 @@ ar:
|
||||
zone: "منطقة"
|
||||
calculator: "آلة حاسبة"
|
||||
display: "عرض"
|
||||
both: "كل من تسجيل الخروج والمكتب الخلفي"
|
||||
back_end: "المكتب الخلفي فقط"
|
||||
no_shipping_methods_found: "لم يتم العثور على طرق الشحن"
|
||||
new:
|
||||
new_shipping_method: "طريقة الشحن الجديدة"
|
||||
@@ -3037,6 +3235,9 @@ ar:
|
||||
form:
|
||||
categories: "التصنيفات"
|
||||
zones: "مناطق"
|
||||
both: "كل من تسجيل الخروج والمكتب الخلفي"
|
||||
back_end: "المكتب الخلفي فقط"
|
||||
deactivation_warning: "يمكن أن يؤدي إلغاء تنشيط طريقة الشحن إلى اختفاء طريقة الشحن من قائمتك. بدلاً من ذلك ، يمكنك إخفاء طريقة الشحن من صفحة الخروج عن طريق تعيين الخيار\"عرض\" إلى\"المكتب الخلفي فقط\"."
|
||||
payment_methods:
|
||||
index:
|
||||
payment_methods: "طريقة الدفع"
|
||||
@@ -3048,8 +3249,11 @@ ar:
|
||||
display: "عرض"
|
||||
active: "نشط"
|
||||
both: "على حد سواء"
|
||||
front_end: "الخروج فقط"
|
||||
back_end: "المكتب الخلفي فقط"
|
||||
active_yes: "نعم"
|
||||
active_no: "لا"
|
||||
no_payment_methods_found: "لم يتم العثور على طرق دفع"
|
||||
new:
|
||||
new_payment_method: "طريقة الدفع الجديدة"
|
||||
back_to_payment_methods_list: "العودة إلى قائمة طرق الدفع"
|
||||
@@ -3078,7 +3282,11 @@ ar:
|
||||
active: "نشط"
|
||||
active_yes: "نعم"
|
||||
active_no: "لا"
|
||||
both: "كل من تسجيل الخروج والمكتب الخلفي"
|
||||
front_end: "الخروج فقط"
|
||||
back_end: "المكتب الخلفي فقط"
|
||||
tags: "الاوسمة"
|
||||
deactivation_warning: "يمكن أن يؤدي إلغاء تنشيط طريقة الدفع إلى اختفاء طريقة الدفع من قائمتك. بدلاً من ذلك ، يمكنك إخفاء طريقة الدفع من صفحة الخروج عن طريق تعيين الخيار \"عرض\" إلى\"المكتب الخلفي فقط\"."
|
||||
providers:
|
||||
provider: "مزود"
|
||||
payments:
|
||||
@@ -3086,6 +3294,8 @@ ar:
|
||||
stripe:
|
||||
error_saving_payment: خطأ في حفظ الدفعة
|
||||
submitting_payment: تقديم الدفعة ...
|
||||
paypal:
|
||||
no_payment_via_admin_backend: لا يمكن التقاط مدفوعات Paypal في Backoffice
|
||||
products:
|
||||
image_upload_error: "لم يتم التعرف على صورة المنتج. يرجى تحميل صورة بتنسيق PNG أو JPG."
|
||||
new:
|
||||
@@ -3139,6 +3349,8 @@ ar:
|
||||
bulk_coop_allocation: 'معظم التعاونية - تخصيص'
|
||||
bulk_coop_packing_sheets: 'معظم التعاونية - صحائف التعبئة'
|
||||
bulk_coop_customer_payments: ' الجمعية التعاونية - مدفوعات العملاء بالجملة'
|
||||
customer_names_message:
|
||||
customer_names_tip: "إذا كانت أسماء العملاء مخفية للطلبات التي قدمتها ، فيمكنك الاتصال بالموزع والسؤال عما إذا كان بإمكانهم تحديث تفضيلات متجرهم للسماح لمورديهم بمشاهدة أسماء العملاء."
|
||||
users:
|
||||
index:
|
||||
listing_users: "قائمة المستخدمين"
|
||||
@@ -3180,6 +3392,8 @@ ar:
|
||||
price: "السعر"
|
||||
display_as: "عرض ب"
|
||||
display_name: "اسم العرض"
|
||||
display_as_placeholder: 'على سبيل المثال 2 كجم'
|
||||
display_name_placeholder: 'على سبيل المثال طماطم'
|
||||
autocomplete:
|
||||
out_of_stock: "غير متوفر"
|
||||
producer_name: "المنتج"
|
||||
@@ -3219,6 +3433,7 @@ ar:
|
||||
format: '٪ س-٪ م-%d'
|
||||
js_format: 'يوم-شهر-سنة'
|
||||
orders:
|
||||
error_flash_for_unavailable_items: "عنصر في سلة التسوق الخاصة بك أصبح غير متوفر. يرجى تحديث الكميات المحددة."
|
||||
edit:
|
||||
login_to_view_order: "يرجى تسجيل الدخول لعرض طلبك."
|
||||
bought:
|
||||
@@ -3246,6 +3461,14 @@ ar:
|
||||
invalid: غير صالحة
|
||||
order_mailer:
|
||||
cancel_email:
|
||||
customer_greeting: "عزيزي %{name} ،"
|
||||
instructions_html: "تم إلغاء طلبك مع <strong>%{distributor}</strong> . يرجى الاحتفاظ بمعلومات الإلغاء هذه في سجلاتك."
|
||||
dont_cancel: "إذا غيرت رأيك أو لا ترغب في إلغاء هذا الطلب ، فيرجى الاتصال بـ %{email}"
|
||||
order_summary_canceled_html: "<strong>ملخص الطلب # %{number} [ملغي]</strong>"
|
||||
details: "إليك تفاصيل ما طلبته:"
|
||||
unpaid_order: "لم يتم سداد طلبك ، لذا لم يتم رد الأموال"
|
||||
paid_order: "تم دفع طلبك حتى أعاد %{distributor} المبلغ بالكامل"
|
||||
credit_order: "تم دفع طلبك حتى تم إضافة رصيد إلى حسابك"
|
||||
subject: "إلغاء الطلب"
|
||||
confirm_email:
|
||||
subject: "تأكيد الطلب"
|
||||
@@ -3273,6 +3496,11 @@ ar:
|
||||
thanks: "شكرا لك على اعمالك."
|
||||
track_information: "معلومات التتبع : %{tracking}"
|
||||
track_link: "رابط التتبع: %{url}"
|
||||
test_mailer:
|
||||
test_email:
|
||||
greeting: "تهانينا!"
|
||||
message: "إذا كنت قد تلقيت هذا البريد الإلكتروني ، فإن إعدادات بريدك الإلكتروني صحيحة."
|
||||
subject: "اختبار البريد"
|
||||
order_state:
|
||||
address: العنوان
|
||||
adjustments: التعديلات
|
||||
@@ -3355,3 +3583,12 @@ ar:
|
||||
shipment:
|
||||
cannot_ready: "لا يمكن تجهيز الشحنة"
|
||||
invalid_taxonomy_id: "معرف التصنيف غير صالح."
|
||||
activerecord:
|
||||
models:
|
||||
spree/payment:
|
||||
zero: المدفوعات
|
||||
one: دفع
|
||||
two: المدفوعات
|
||||
few: المدفوعات
|
||||
many: المدفوعات
|
||||
other: الدفعات
|
||||
|
||||
@@ -227,6 +227,7 @@ ca:
|
||||
enterprises: Organitzacions
|
||||
enterprise_groups: Grups
|
||||
reports: Informes
|
||||
listing_reports: Llistat d'informes
|
||||
variant_overrides: Inventari
|
||||
import: Importa
|
||||
spree_products: Productes Spree
|
||||
@@ -722,6 +723,10 @@ ca:
|
||||
enable_subscriptions_tip: "Habilitar la funcionalitat de subscripcions?"
|
||||
enable_subscriptions_false: "Deshabilitat"
|
||||
enable_subscriptions_true: "Habilitat"
|
||||
customer_names_in_reports: "Noms de consumidores als informes"
|
||||
customer_names_tip: "Habiliteu als proveïdors veure els noms dels vostres clients als informes"
|
||||
customer_names_false: "Deshabilitat"
|
||||
customer_names_true: "Habilitat"
|
||||
shopfront_message: "Missatge de la botiga"
|
||||
shopfront_message_placeholder: >
|
||||
Un missatge opcional per donar la benvinguda als clients i explicar
|
||||
@@ -2055,7 +2060,6 @@ ca:
|
||||
spree_user_enterprise_limit_error: "^ %{email} no està autoritzat a tenir més organitzacions (el límit és %{enterprise_limit})."
|
||||
spree_variant_product_error: ha de tenir com a mínim una variant
|
||||
your_profil_live: "El teu perfil online"
|
||||
on_ofn_map: "al mapa d'Open Food Network"
|
||||
see: "Veure"
|
||||
live: "online"
|
||||
manage: "Gestiona"
|
||||
@@ -2540,7 +2544,7 @@ ca:
|
||||
paid: "pagat"
|
||||
pending: "pendents"
|
||||
processing: "processant"
|
||||
void: "buit"
|
||||
void: "pendent"
|
||||
invalid: "invàlid"
|
||||
resend_user_email_confirmation:
|
||||
resend: "Reenviar"
|
||||
@@ -2775,6 +2779,8 @@ ca:
|
||||
adjustments: "Ajustaments"
|
||||
payments: "Pagaments"
|
||||
return_authorizations: "Autoritzacions de devolució"
|
||||
credit_owed: "Crèdit a deure"
|
||||
new_adjustment: "Nou ajustament"
|
||||
payment: "Pagament"
|
||||
payment_method: "Mètode de pagament"
|
||||
shipment: "Enviament"
|
||||
@@ -2843,8 +2849,8 @@ ca:
|
||||
continue: "Continua"
|
||||
fill_in_customer_info: "Ompliu la informació de la consumidora"
|
||||
new_payment: "Nou pagament"
|
||||
capture: "Captura"
|
||||
void: "Buit"
|
||||
capture: "Pagat"
|
||||
void: "Pendent"
|
||||
login: "Inicia sessió"
|
||||
password: "Contrasenya"
|
||||
signature: "Signatura"
|
||||
@@ -2975,6 +2981,11 @@ ca:
|
||||
one: "Un error va prohibir guardar aquest registre:"
|
||||
other: "%{count} errors han impedit guardar aquest registre:"
|
||||
there_were_problems_with_the_following_fields: "Hi ha hagut problemes amb els camps següents"
|
||||
payments_list:
|
||||
date_time: "Data i hora"
|
||||
amount: "Quantitat"
|
||||
payment_method: "Mètode de pagament"
|
||||
payment_state: "Estat del pagament"
|
||||
errors:
|
||||
messages:
|
||||
blank: "no es pot deixar en blanc"
|
||||
@@ -3056,7 +3067,7 @@ ca:
|
||||
index:
|
||||
listing_orders: "Llistat comandes"
|
||||
new_order: "Nova comanda"
|
||||
capture: "Captura"
|
||||
capture: "Pagat"
|
||||
ship: "Enviament"
|
||||
edit: "Editar"
|
||||
order_not_updated: "La comanda no s'ha pogut actualitzar"
|
||||
@@ -3190,7 +3201,7 @@ ca:
|
||||
error_saving_payment: Error en desar el pagament
|
||||
submitting_payment: S'està lliurant el pagament...
|
||||
paypal:
|
||||
no_payment_via_admin_backend: Els pagaments amb Paypal no es poden capturar des de l'administració
|
||||
no_payment_via_admin_backend: Els pagaments amb Paypal no es poden marcar com pagats des de l'administració
|
||||
products:
|
||||
image_upload_error: "No s'ha reconegut la imatge del producte. Carregueu una imatge en format PNG o JPG."
|
||||
new:
|
||||
@@ -3244,6 +3255,8 @@ ca:
|
||||
bulk_coop_allocation: 'Compra grupal - Assignació'
|
||||
bulk_coop_packing_sheets: 'Compra grupal - Fulls de preparació de cistelles'
|
||||
bulk_coop_customer_payments: 'Compra grupal - Pagaments de les consumidores'
|
||||
customer_names_message:
|
||||
customer_names_tip: "Si els noms de les consumidores per a les comandes que heu subministrat apareixen amagats, podeu contactar amb la distribuïdora i preguntar-los si poden actualitzar les seves preferències de la botiga per permetre als seus proveïdors visualitzar els noms de les consumidores."
|
||||
users:
|
||||
index:
|
||||
listing_users: "Llistat d'usuàries"
|
||||
@@ -3350,7 +3363,7 @@ ca:
|
||||
paid: pagat
|
||||
pending: pendents
|
||||
processing: processant
|
||||
void: buit
|
||||
void: pendent
|
||||
invalid: invàlid
|
||||
order_mailer:
|
||||
cancel_email:
|
||||
@@ -3389,6 +3402,11 @@ ca:
|
||||
thanks: "Gràcies per la teva compra."
|
||||
track_information: "Informació del seguiment: %{tracking}"
|
||||
track_link: "Enllaç del seguiment: %{url}"
|
||||
test_mailer:
|
||||
test_email:
|
||||
greeting: "Enhorabona!"
|
||||
message: "Si heu rebut aquest correu electrònic, la vostra configuració de correu electrònic és correcta."
|
||||
subject: "Correu de prova"
|
||||
order_state:
|
||||
address: adreça
|
||||
adjustments: ajustaments
|
||||
@@ -3471,3 +3489,8 @@ ca:
|
||||
shipment:
|
||||
cannot_ready: "No es pot fer l'enviament."
|
||||
invalid_taxonomy_id: "Identificador de taxonomia no vàlid."
|
||||
activerecord:
|
||||
models:
|
||||
spree/payment:
|
||||
one: Pagament
|
||||
other: Pagaments
|
||||
|
||||
@@ -711,6 +711,8 @@ de_DE:
|
||||
enable_subscriptions_tip: "Abo-Funktionalität aktivieren?"
|
||||
enable_subscriptions_false: "deaktiviert"
|
||||
enable_subscriptions_true: "aktiviert"
|
||||
customer_names_false: "deaktiviert"
|
||||
customer_names_true: "aktiviert"
|
||||
shopfront_message: "Laden-Nachricht"
|
||||
shopfront_message_placeholder: >
|
||||
Eine optionale Nachricht, um Kunden willkommen zu heißen und zu erklären,
|
||||
@@ -2019,7 +2021,6 @@ de_DE:
|
||||
spree_user_enterprise_limit_error: "^ %{email} darf keine weiteren Unternehmen besitzen (Limit ist %{enterprise_limit})."
|
||||
spree_variant_product_error: muss mindestens eine Variante haben
|
||||
your_profil_live: "Dein Profil live"
|
||||
on_ofn_map: "auf der Open Food Network Karte"
|
||||
see: "Sehen"
|
||||
live: "Leben"
|
||||
manage: "Verwalten"
|
||||
@@ -2915,6 +2916,11 @@ de_DE:
|
||||
options: "Optionen"
|
||||
actions:
|
||||
update: "Aktualisieren"
|
||||
shared:
|
||||
payments_list:
|
||||
amount: "Betrag"
|
||||
payment_method: "Zahlungsart"
|
||||
payment_state: "Zahlungsstatus"
|
||||
errors:
|
||||
messages:
|
||||
blank: "kann nicht leer sein"
|
||||
|
||||
@@ -84,7 +84,7 @@ en:
|
||||
messages:
|
||||
inclusion: "is not included in the list"
|
||||
models:
|
||||
order_management/subscriptions/validator:
|
||||
order_management/subscriptions/validator:
|
||||
attributes:
|
||||
subscription_line_items:
|
||||
at_least_one_product: "^Please add at least one product"
|
||||
@@ -256,6 +256,7 @@ en:
|
||||
enterprises: Enterprises
|
||||
enterprise_groups: Groups
|
||||
reports: Reports
|
||||
listing_reports: Listing Reports
|
||||
variant_overrides: Inventory
|
||||
import: Import
|
||||
spree_products: Spree Products
|
||||
@@ -777,6 +778,10 @@ en:
|
||||
enable_subscriptions_tip: "Enable subscriptions functionality?"
|
||||
enable_subscriptions_false: "Disabled"
|
||||
enable_subscriptions_true: "Enabled"
|
||||
customer_names_in_reports: "Customer Names in Reports"
|
||||
customer_names_tip: "Enable your suppliers to see your customers names in reports"
|
||||
customer_names_false: "Disabled"
|
||||
customer_names_true: "Enabled"
|
||||
shopfront_message: "Shopfront Message"
|
||||
shopfront_message_placeholder: >
|
||||
An optional message to welcome customers and explain how to shop with you. If text is entered here it will be displayed in a home tab when customers first arrive at your shopfront.
|
||||
@@ -2182,7 +2187,6 @@ See the %{link} to find out more about %{sitename}'s features and to start using
|
||||
spree_user_enterprise_limit_error: "^%{email} is not permitted to own any more enterprises (limit is %{enterprise_limit})."
|
||||
spree_variant_product_error: must have at least one variant
|
||||
your_profil_live: "Your profile live"
|
||||
on_ofn_map: "on the Open Food Network map"
|
||||
see: "See"
|
||||
live: "live"
|
||||
manage: "Manage"
|
||||
@@ -2767,6 +2771,11 @@ See the %{link} to find out more about %{sitename}'s features and to start using
|
||||
signup_or_login: "Start By Signing Up (or logging in)"
|
||||
have_an_account: "Already have an account?"
|
||||
action_login: "Log in now."
|
||||
stripe_elements:
|
||||
unknown_error_from_stripe: |
|
||||
There was a problem setting up your card in our payments gateway.
|
||||
Please refresh the page and try again, if it fails a second time,
|
||||
please contact us for support.
|
||||
|
||||
# Singular and plural forms of commonly used words.
|
||||
# We use these entries to pluralize unit names in every language.
|
||||
@@ -2911,6 +2920,8 @@ See the %{link} to find out more about %{sitename}'s features and to start using
|
||||
adjustments: "Adjustments"
|
||||
payments: "Payments"
|
||||
return_authorizations: "Return Authorizations"
|
||||
credit_owed: "Credit Owed"
|
||||
new_adjustment: "New Adjustment"
|
||||
|
||||
payment: "Payment"
|
||||
payment_method: "Payment Method"
|
||||
@@ -3134,6 +3145,11 @@ See the %{link} to find out more about %{sitename}'s features and to start using
|
||||
one: "1 error prohibited this record from being saved:"
|
||||
other: "%{count} errors prohibited this record from being saved:"
|
||||
there_were_problems_with_the_following_fields: "There were problems with the following fields"
|
||||
payments_list:
|
||||
date_time: "Date/time"
|
||||
amount: "Amount"
|
||||
payment_method: "Payment Method"
|
||||
payment_state: "Payment State"
|
||||
errors:
|
||||
messages:
|
||||
blank: "can't be blank"
|
||||
@@ -3403,6 +3419,8 @@ See the %{link} to find out more about %{sitename}'s features and to start using
|
||||
bulk_coop_allocation: 'Bulk Co-op - Allocation'
|
||||
bulk_coop_packing_sheets: 'Bulk Co-op - Packing Sheets'
|
||||
bulk_coop_customer_payments: 'Bulk Co-op - Customer Payments'
|
||||
customer_names_message:
|
||||
customer_names_tip: "If customer names are hidden for orders you have supplied, you can contact the distributor and ask if they can update their shop preferences to allow their suppliers to view customer names."
|
||||
users:
|
||||
index:
|
||||
listing_users: "Listing Users"
|
||||
@@ -3635,3 +3653,8 @@ See the %{link} to find out more about %{sitename}'s features and to start using
|
||||
shipment:
|
||||
cannot_ready: "Cannot ready shipment."
|
||||
invalid_taxonomy_id: "Invalid taxonomy id."
|
||||
activerecord:
|
||||
models:
|
||||
spree/payment:
|
||||
one: Payment
|
||||
other: Payments
|
||||
|
||||
@@ -702,6 +702,8 @@ en_AU:
|
||||
enable_subscriptions_tip: "Enable subscriptions functionality?"
|
||||
enable_subscriptions_false: "Disabled"
|
||||
enable_subscriptions_true: "Enabled"
|
||||
customer_names_false: "Disabled"
|
||||
customer_names_true: "Enabled"
|
||||
shopfront_message: "\"Home\" message"
|
||||
shopfront_message_placeholder: >
|
||||
Create your home page content to welcome customers and explain how people
|
||||
@@ -2015,7 +2017,6 @@ en_AU:
|
||||
spree_user_enterprise_limit_error: "^%{email} is not permitted to own any more enterprises (limit is %{enterprise_limit})."
|
||||
spree_variant_product_error: must have at least one variant
|
||||
your_profil_live: "Your profile live"
|
||||
on_ofn_map: "on the Open Food Network map"
|
||||
see: "See"
|
||||
live: "live"
|
||||
manage: "Manage"
|
||||
@@ -2830,6 +2831,11 @@ en_AU:
|
||||
options: "Options"
|
||||
actions:
|
||||
update: "Update"
|
||||
shared:
|
||||
payments_list:
|
||||
amount: "Amount"
|
||||
payment_method: "Payment Method"
|
||||
payment_state: "Payment State"
|
||||
errors:
|
||||
messages:
|
||||
blank: "can't be blank"
|
||||
|
||||
@@ -691,6 +691,8 @@ en_BE:
|
||||
enable_subscriptions_tip: "Enable subscriptions functionality?"
|
||||
enable_subscriptions_false: "Disabled"
|
||||
enable_subscriptions_true: "Enabled"
|
||||
customer_names_false: "Disabled"
|
||||
customer_names_true: "Enabled"
|
||||
shopfront_message: "Shopfront Message"
|
||||
shopfront_message_link_tooltip: "Insert / edit link"
|
||||
shopfront_message_link_prompt: "Please enter a URL to insert"
|
||||
@@ -1975,7 +1977,6 @@ en_BE:
|
||||
spree_user_enterprise_limit_error: "^%{email} is not permitted to own any more enterprises (limit is %{enterprise_limit})."
|
||||
spree_variant_product_error: must have at least one variant
|
||||
your_profil_live: "Your profile live"
|
||||
on_ofn_map: "on the Open Food Network map"
|
||||
see: "See"
|
||||
live: "live"
|
||||
manage: "Manage"
|
||||
@@ -2778,6 +2779,11 @@ en_BE:
|
||||
weight: Weight (per kg)
|
||||
actions:
|
||||
update: "Update"
|
||||
shared:
|
||||
payments_list:
|
||||
amount: "Amount"
|
||||
payment_method: "Payment Method"
|
||||
payment_state: "Payment State"
|
||||
errors:
|
||||
messages:
|
||||
blank: "can't be blank"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user