spree_core 4.8.3 → 4.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE.md +57 -0
- data/app/finders/spree/line_items/find_by_variant.rb +4 -2
- data/app/finders/spree/orders/find_complete.rb +3 -13
- data/app/finders/spree/orders/find_current.rb +3 -1
- data/app/finders/spree/orders/finder_helper.rb +17 -0
- data/app/finders/spree/products/find.rb +1 -1
- data/app/finders/spree/variants/find.rb +30 -0
- data/app/models/spree/address.rb +12 -2
- data/app/models/spree/adjustment.rb +5 -0
- data/app/models/spree/asset.rb +8 -0
- data/app/models/spree/calculator/flat_rate.rb +3 -0
- data/app/models/spree/calculator/flexi_rate.rb +3 -0
- data/app/models/spree/calculator/percent_on_line_item.rb +3 -0
- data/app/models/spree/calculator/shipping/flat_rate.rb +13 -1
- data/app/models/spree/cms_section_image.rb +0 -6
- data/app/models/spree/customer_return.rb +1 -0
- data/app/models/spree/fulfilment_changer.rb +1 -0
- data/app/models/spree/icon.rb +0 -6
- data/app/models/spree/image/configuration/active_storage.rb +0 -8
- data/app/models/spree/image.rb +17 -0
- data/app/models/spree/line_item.rb +26 -7
- data/app/models/spree/option_value_variant.rb +4 -0
- data/app/models/spree/order/currency_updater.rb +2 -2
- data/app/models/spree/order/webhooks.rb +19 -0
- data/app/models/spree/order.rb +17 -6
- data/app/models/spree/order_merger.rb +6 -0
- data/app/models/spree/payment/gateway_options.rb +4 -0
- data/app/models/spree/payment/webhooks.rb +15 -0
- data/app/models/spree/payment.rb +7 -7
- data/app/models/spree/price.rb +53 -1
- data/app/models/spree/product/webhooks.rb +17 -0
- data/app/models/spree/product.rb +7 -9
- data/app/models/spree/promotion/actions/free_shipping.rb +13 -0
- data/app/models/spree/promotion/rules/first_order.rb +6 -1
- data/app/models/spree/promotion.rb +2 -2
- data/app/models/spree/promotion_handler/coupon.rb +3 -2
- data/app/models/spree/refund.rb +14 -2
- data/app/models/spree/reimbursement/emails.rb +11 -0
- data/app/models/spree/reimbursement.rb +1 -6
- data/app/models/spree/role_user.rb +1 -1
- data/app/models/spree/shipment/emails.rb +11 -0
- data/app/models/spree/shipment/webhooks.rb +11 -0
- data/app/models/spree/shipment.rb +60 -7
- data/app/models/spree/shipment_handler.rb +2 -6
- data/app/models/spree/shipping_method.rb +24 -2
- data/app/models/spree/shipping_method_zone.rb +4 -2
- data/app/models/spree/shipping_rate.rb +1 -1
- data/app/models/spree/stock/package.rb +4 -0
- data/app/models/spree/stock/quantifier.rb +22 -4
- data/app/models/spree/stock_item/webhooks.rb +6 -0
- data/app/models/spree/stock_item.rb +1 -3
- data/app/models/spree/stock_location.rb +15 -0
- data/app/models/spree/stock_movement/webhooks.rb +6 -0
- data/app/models/spree/stock_movement.rb +1 -3
- data/app/models/spree/store.rb +2 -9
- data/app/models/spree/store_credit.rb +11 -12
- data/app/models/spree/store_favicon_image.rb +0 -6
- data/app/models/spree/store_logo.rb +0 -5
- data/app/models/spree/store_mailer_logo.rb +0 -6
- data/app/models/spree/tax_rate.rb +3 -1
- data/app/models/spree/taxon.rb +83 -17
- data/app/models/spree/taxon_image/configuration/active_storage.rb +0 -6
- data/app/models/spree/taxonomy.rb +1 -0
- data/app/models/spree/variant/webhooks.rb +6 -0
- data/app/models/spree/variant.rb +29 -6
- data/app/models/spree/wishlist.rb +9 -0
- data/app/presenters/spree/variants/options_presenter.rb +34 -2
- data/app/services/spree/cart/add_item.rb +2 -0
- data/app/services/spree/cart/destroy.rb +14 -4
- data/app/services/spree/seeds/all.rb +3 -0
- data/app/services/spree/seeds/payment_methods.rb +18 -0
- data/app/services/spree/seeds/stock_locations.rb +1 -1
- data/app/services/spree/seeds/zones.rb +19 -19
- data/app/services/spree/tracking_numbers/base_service.rb +19 -0
- data/config/locales/en.yml +2 -0
- data/db/migrate/20240623172111_add_deleted_at_to_spree_stock_locations.rb +6 -0
- data/db/migrate/20240725124530_add_refunder_to_spree_refunds.rb +6 -0
- data/db/migrate/20240822163534_add_pretty_name_to_spree_taxons.rb +9 -0
- data/lib/spree/core/components.rb +6 -0
- data/lib/spree/core/controller_helpers/order.rb +5 -5
- data/lib/spree/core/dependencies.rb +5 -1
- data/lib/spree/core/engine.rb +1 -1
- data/lib/spree/core/preferences/preferable.rb +4 -2
- data/lib/spree/core/preferences/preferable_class_methods.rb +3 -2
- data/lib/spree/core/runtime_configuration.rb +1 -0
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/core/webhooks.rb +15 -7
- data/lib/spree/core.rb +1 -0
- data/lib/spree/money.rb +1 -1
- data/lib/spree/permitted_attributes.rb +1 -0
- data/lib/spree/testing_support/authorization_helpers.rb +2 -2
- data/lib/spree/testing_support/capybara_config.rb +8 -4
- data/lib/spree/testing_support/common_rake.rb +1 -1
- data/spree_core.gemspec +5 -3
- metadata +54 -8
- data/LICENSE +0 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ef1a05dcfe29482a9f538a00cbf53f30fb26b25cc789e6935b1c502fa7d670ba
|
4
|
+
data.tar.gz: 0b685feeca4b4de334ef20c454edf4b83476d7275dca33617780b03df659023e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d18e35dc1286e0053e044ae360e0b626ccab034e356a8ca6396303a8c90c18041c22ee94fdfdcb7e08ed8856f56416a81efed9e864088b351a68684d972b95c0
|
7
|
+
data.tar.gz: e9338463f6da5a8b40353001e24285c0cf5b0fea045a66ff536531022c7ea1ab82c9507ce456652e5afcee6d8a8166d577645b083f79371a95d3d0c30be7eeca
|
data/LICENSE.md
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
# License
|
2
|
+
|
3
|
+
Copyright © 2024-present, Vendo Connect Inc.
|
4
|
+
|
5
|
+
Copyright © 2015-2024, Spark Solutions Sp. z o.o.
|
6
|
+
|
7
|
+
Copyright © 2007-2015, Spree Commerce Inc.
|
8
|
+
|
9
|
+
Spree Commerce is a free, open-source eCommerce framework giving you full control and customizability.
|
10
|
+
|
11
|
+
For **Spree Commerce versions 4.10** and later in the [spree/spree](https://github.com/spree/spree) repository two licenses apply simultaneously and users are required to comply with the terms of these two licenses at the same time:
|
12
|
+
|
13
|
+
* [AGPL-3.0](https://opensource.org/license/agpl-v3) - for all contributions from version 4.10 onwards
|
14
|
+
|
15
|
+
* [BSD-3-Clause](https://opensource.org/license/bsd-3-clause) - for all other contributions predating version 4.10
|
16
|
+
Effectively, for versions 4.10 and upwards **AGPL-3.0** license applies.
|
17
|
+
|
18
|
+
**Spree Commerce versions 4.9** and earlier in the [spree/spree](https://github.com/spree/spree) repository are available under the **BSD-3-Clause** license and users are required to comply with its terms.
|
19
|
+
|
20
|
+
If you’d like to use Spree Commerce without the AGPL-3.0 restrictions e.g. for a **SaaS** business, please talk to us about obtaining a [Commercial License](#commercial-license).
|
21
|
+
|
22
|
+
All third party components incorporated into this software are licensed under the original license provided by the owner of the applicable component.
|
23
|
+
|
24
|
+
Please refer to our [Licensing FAQ](https://spreecommerce.org/why-spree-is-changing-its-open-source-license-to-agpl-3-0-and-introducing-a-commercial-license/) in case of questions.
|
25
|
+
|
26
|
+
## AGPL-3.0 License - Spree 4.10 upwards
|
27
|
+
|
28
|
+
If you decide to accept the AGPL-3.0 license by using Spree Commerce version 4.10 or later, you must comply with the following terms:
|
29
|
+
|
30
|
+
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
31
|
+
|
32
|
+
This program is distributed in the hope that it will be useful,
|
33
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
34
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
35
|
+
GNU Affero General Public License for more details.
|
36
|
+
|
37
|
+
You should have received a copy of the GNU Affero General Public License
|
38
|
+
along with this program. If not, see [https://www.gnu.org/licenses/](https://www.gnu.org/licenses/).
|
39
|
+
|
40
|
+
## BSD 3-Clause License
|
41
|
+
|
42
|
+
If you decide to accept the BSD-3-Clause license by using Spree Commerce, you must comply with the following terms:
|
43
|
+
|
44
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
45
|
+
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
46
|
+
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
47
|
+
Neither the name of Spree Commerce Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
48
|
+
|
49
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
50
|
+
|
51
|
+
## Commercial License
|
52
|
+
|
53
|
+
Should you decide to use Spree Commerce version 4.10 or later for commercial redistribution (eg. SaaS) - also known as Commercial Distribution - you must do so in accordance with the terms and conditions contained in a separate written agreement between you and [Vendo Connect Inc.](https://www.getvendo.com/).
|
54
|
+
|
55
|
+
For more information about the Commercial License (CL) please contact [sales@getvendo.com](mailto:sales@getvendo.com).
|
56
|
+
|
57
|
+
Please refer to our [Licensing FAQ](https://spreecommerce.org/why-spree-is-changing-its-open-source-license-to-agpl-3-0-and-introducing-a-commercial-license/) in case of questions.
|
@@ -2,11 +2,13 @@ module Spree
|
|
2
2
|
module LineItems
|
3
3
|
class FindByVariant
|
4
4
|
def execute(order:, variant:, options: {})
|
5
|
-
order.line_items.detect
|
6
|
-
next unless line_item.variant_id == variant.id
|
5
|
+
line_item = order.line_items.loaded? ? order.line_items.detect { |li| li.variant_id == variant.id } : order.line_items.find_by(variant_id: variant.id)
|
7
6
|
|
7
|
+
if line_item
|
8
8
|
Spree::Dependencies.cart_compare_line_items_service.constantize.call(order: order, line_item: line_item, options: options).value
|
9
9
|
end
|
10
|
+
|
11
|
+
line_item
|
10
12
|
end
|
11
13
|
end
|
12
14
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module Spree
|
2
2
|
module Orders
|
3
3
|
class FindComplete
|
4
|
+
include Spree::Orders::FinderHelper
|
5
|
+
|
4
6
|
attr_reader :user, :number, :token, :store
|
5
7
|
|
6
8
|
def initialize(user: nil, number: nil, token: nil, store: nil)
|
@@ -22,7 +24,7 @@ module Spree
|
|
22
24
|
private
|
23
25
|
|
24
26
|
def scope
|
25
|
-
user? ? user.orders.complete.includes(
|
27
|
+
user? ? user.orders.complete.includes(order_includes) : Spree::Order.complete.includes(order_includes)
|
26
28
|
end
|
27
29
|
|
28
30
|
def user?
|
@@ -64,18 +66,6 @@ module Spree
|
|
64
66
|
|
65
67
|
orders.where(store: store)
|
66
68
|
end
|
67
|
-
|
68
|
-
def scope_includes
|
69
|
-
{
|
70
|
-
line_items: [
|
71
|
-
variant: [
|
72
|
-
:images,
|
73
|
-
option_values: :option_type,
|
74
|
-
product: :product_properties,
|
75
|
-
]
|
76
|
-
]
|
77
|
-
}
|
78
|
-
end
|
79
69
|
end
|
80
70
|
end
|
81
71
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module Spree
|
2
2
|
module Orders
|
3
3
|
class FindCurrent
|
4
|
+
include Spree::Orders::FinderHelper
|
5
|
+
|
4
6
|
def execute(user:, store:, **params)
|
5
7
|
params = params.merge(store_id: store.id)
|
6
8
|
|
@@ -15,7 +17,7 @@ module Spree
|
|
15
17
|
private
|
16
18
|
|
17
19
|
def incomplete_orders
|
18
|
-
Spree::Order.incomplete.not_canceled
|
20
|
+
Spree::Order.incomplete.not_canceled.includes(order_includes)
|
19
21
|
end
|
20
22
|
end
|
21
23
|
end
|
@@ -263,7 +263,7 @@ module Spree
|
|
263
263
|
def taxon_ids(taxons_ids)
|
264
264
|
return if taxons_ids.nil? || taxons_ids.to_s.blank?
|
265
265
|
|
266
|
-
taxons = store.
|
266
|
+
taxons = Spree::Taxon.for_store(store).where(id: taxons_ids.to_s.split(','))
|
267
267
|
taxons.map(&:cached_self_and_descendants_ids).flatten.compact.uniq.map(&:to_s)
|
268
268
|
end
|
269
269
|
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Spree
|
2
|
+
module Variants
|
3
|
+
class Find
|
4
|
+
def initialize(scope:, params:)
|
5
|
+
@scope = scope
|
6
|
+
@options = params.dig(:filter, :options).try(:to_unsafe_hash)
|
7
|
+
end
|
8
|
+
|
9
|
+
def execute
|
10
|
+
variants = by_options(scope)
|
11
|
+
variants.distinct
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
attr_reader :scope, :options
|
17
|
+
|
18
|
+
def options?
|
19
|
+
options.present?
|
20
|
+
end
|
21
|
+
|
22
|
+
def by_options(variants)
|
23
|
+
return variants unless options?
|
24
|
+
|
25
|
+
variants_ids = options.map { |key, value| variants.with_option_value(key, value)&.ids }.compact.uniq
|
26
|
+
variants.where(id: variants_ids.reduce(&:intersection))
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/app/models/spree/address.rb
CHANGED
@@ -46,7 +46,9 @@ module Spree
|
|
46
46
|
before_validation :clear_invalid_state_entities, if: -> { country.present? }, on: :update
|
47
47
|
|
48
48
|
with_options presence: true do
|
49
|
-
validates :firstname, :lastname, :
|
49
|
+
validates :firstname, :lastname, if: :require_name?
|
50
|
+
validates :address1, if: :require_street?
|
51
|
+
validates :city, :country
|
50
52
|
validates :zipcode, if: :require_zipcode?
|
51
53
|
validates :phone, if: :require_phone?
|
52
54
|
end
|
@@ -137,12 +139,20 @@ module Spree
|
|
137
139
|
country ? country.zipcode_required? : true
|
138
140
|
end
|
139
141
|
|
142
|
+
def require_name?
|
143
|
+
true
|
144
|
+
end
|
145
|
+
|
146
|
+
def require_street?
|
147
|
+
true
|
148
|
+
end
|
149
|
+
|
140
150
|
def editable?
|
141
151
|
new_record? || (shipments.empty? && !Order.complete.where('bill_address_id = ? OR ship_address_id = ?', id, id).exists?)
|
142
152
|
end
|
143
153
|
|
144
154
|
def can_be_deleted?
|
145
|
-
shipments.empty? && !Order.where('bill_address_id = ? OR ship_address_id = ?', id, id).exists?
|
155
|
+
shipments.empty? && !Order.complete.where('bill_address_id = ? OR ship_address_id = ?', id, id).exists?
|
146
156
|
end
|
147
157
|
|
148
158
|
def check
|
@@ -64,6 +64,7 @@ module Spree
|
|
64
64
|
scope :charge, -> { where("#{quoted_table_name}.amount >= 0") }
|
65
65
|
scope :credit, -> { where("#{quoted_table_name}.amount < 0") }
|
66
66
|
scope :nonzero, -> { where("#{quoted_table_name}.amount != 0") }
|
67
|
+
scope :non_zero, -> { where.not(amount: [nil, 0]) }
|
67
68
|
scope :promotion, -> { where(source_type: 'Spree::PromotionAction') }
|
68
69
|
scope :return_authorization, -> { where(source_type: 'Spree::ReturnAuthorization') }
|
69
70
|
scope :is_included, -> { where(included: true) }
|
@@ -87,6 +88,10 @@ module Spree
|
|
87
88
|
source_type == 'Spree::PromotionAction'
|
88
89
|
end
|
89
90
|
|
91
|
+
def tax?
|
92
|
+
source_type == 'Spree::TaxRate'
|
93
|
+
end
|
94
|
+
|
90
95
|
# Passing a target here would always be recommended as it would avoid
|
91
96
|
# hitting the database again and would ensure you're compute values over
|
92
97
|
# the specific object amount passed here.
|
data/app/models/spree/asset.rb
CHANGED
@@ -8,5 +8,13 @@ module Spree
|
|
8
8
|
|
9
9
|
belongs_to :viewable, polymorphic: true, touch: true
|
10
10
|
acts_as_list scope: [:viewable_id, :viewable_type]
|
11
|
+
|
12
|
+
if Spree.public_storage_service_name
|
13
|
+
has_one_attached :attachment, service: Spree.public_storage_service_name
|
14
|
+
else
|
15
|
+
has_one_attached :attachment
|
16
|
+
end
|
17
|
+
|
18
|
+
default_scope { includes(attachment_attachment: :blob) }
|
11
19
|
end
|
12
20
|
end
|
@@ -4,12 +4,15 @@ module Spree
|
|
4
4
|
class Calculator::FlatRate < Calculator
|
5
5
|
preference :amount, :decimal, default: 0
|
6
6
|
preference :currency, :string, default: -> { Spree::Store.default.default_currency }
|
7
|
+
preference :apply_only_on_full_priced_items, :boolean, default: false
|
7
8
|
|
8
9
|
def self.description
|
9
10
|
Spree.t(:flat_rate_per_order)
|
10
11
|
end
|
11
12
|
|
12
13
|
def compute(object = nil)
|
14
|
+
return 0 if preferred_apply_only_on_full_priced_items && object&.variant&.compare_at_amount_in(object.currency).present?
|
15
|
+
|
13
16
|
if object && preferred_currency.casecmp(object.currency.upcase).zero?
|
14
17
|
preferred_amount
|
15
18
|
else
|
@@ -6,6 +6,7 @@ module Spree
|
|
6
6
|
preference :additional_item, :decimal, default: 0.0
|
7
7
|
preference :max_items, :integer, default: 0
|
8
8
|
preference :currency, :string, default: -> { Spree::Store.default.default_currency }
|
9
|
+
preference :apply_only_on_full_priced_items, :boolean, default: false
|
9
10
|
|
10
11
|
def self.description
|
11
12
|
Spree.t(:flexible_rate)
|
@@ -16,6 +17,8 @@ module Spree
|
|
16
17
|
end
|
17
18
|
|
18
19
|
def compute(object)
|
20
|
+
return 0 if preferred_apply_only_on_full_priced_items && object.variant.compare_at_amount_in(object.currency).present?
|
21
|
+
|
19
22
|
compute_from_quantity(object.quantity)
|
20
23
|
end
|
21
24
|
|
@@ -2,12 +2,15 @@ module Spree
|
|
2
2
|
class Calculator
|
3
3
|
class PercentOnLineItem < Calculator
|
4
4
|
preference :percent, :decimal, default: 0
|
5
|
+
preference :apply_only_on_full_priced_items, :boolean, default: false
|
5
6
|
|
6
7
|
def self.description
|
7
8
|
Spree.t(:percent_per_item)
|
8
9
|
end
|
9
10
|
|
10
11
|
def compute(object)
|
12
|
+
return 0 if preferred_apply_only_on_full_priced_items && object.variant.compare_at_amount_in(object.currency).present?
|
13
|
+
|
11
14
|
computed_amount = (object.amount * preferred_percent / 100).round(2)
|
12
15
|
|
13
16
|
# We don't want to cause the promotion adjustments to push the order into a negative total.
|
@@ -6,11 +6,23 @@ module Spree
|
|
6
6
|
preference :amount, :decimal, default: 0
|
7
7
|
preference :currency, :string, default: -> { Spree::Store.default.default_currency }
|
8
8
|
|
9
|
+
preference :minimum_item_total, :decimal, default: nil, nullable: true
|
10
|
+
preference :maximum_item_total, :decimal, default: nil, nullable: true
|
11
|
+
|
12
|
+
preference :minimum_weight, :decimal, default: nil, nullable: true
|
13
|
+
preference :maximum_weight, :decimal, default: nil, nullable: true
|
14
|
+
|
9
15
|
def self.description
|
10
16
|
Spree.t(:shipping_flat_rate_per_order)
|
11
17
|
end
|
12
18
|
|
13
|
-
def compute_package(
|
19
|
+
def compute_package(package)
|
20
|
+
return nil if preferred_minimum_weight.present? && preferred_minimum_weight >= package.weight
|
21
|
+
return nil if preferred_maximum_weight.present? && preferred_maximum_weight < package.weight
|
22
|
+
|
23
|
+
return nil if preferred_minimum_item_total.present? && preferred_minimum_item_total >= package.item_total
|
24
|
+
return nil if preferred_maximum_item_total.present? && preferred_maximum_item_total < package.item_total
|
25
|
+
|
14
26
|
preferred_amount
|
15
27
|
end
|
16
28
|
end
|
@@ -1,11 +1,5 @@
|
|
1
1
|
module Spree
|
2
2
|
class CmsSectionImage < Asset
|
3
|
-
if Spree.public_storage_service_name
|
4
|
-
has_one_attached :attachment, service: Spree.public_storage_service_name
|
5
|
-
else
|
6
|
-
has_one_attached :attachment
|
7
|
-
end
|
8
|
-
|
9
3
|
IMAGE_COUNT = ['one', 'two', 'three']
|
10
4
|
IMAGE_TYPES = ['image/png', 'image/jpg', 'image/jpeg', 'image/gif'].freeze
|
11
5
|
IMAGE_SIZE = ['sm', 'md', 'lg', 'xl']
|
data/app/models/spree/icon.rb
CHANGED
@@ -1,11 +1,5 @@
|
|
1
1
|
module Spree
|
2
2
|
class Icon < Spree::Asset
|
3
|
-
if Spree.public_storage_service_name
|
4
|
-
has_one_attached :attachment, service: Spree.public_storage_service_name
|
5
|
-
else
|
6
|
-
has_one_attached :attachment
|
7
|
-
end
|
8
|
-
|
9
3
|
ICON_TYPES = %i[png jpg jpeg gif svg]
|
10
4
|
|
11
5
|
validates :attachment, attached: true, content_type: ICON_TYPES
|
@@ -5,16 +5,8 @@ module Spree
|
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
|
7
7
|
included do
|
8
|
-
if Spree.public_storage_service_name
|
9
|
-
has_one_attached :attachment, service: Spree.public_storage_service_name
|
10
|
-
else
|
11
|
-
has_one_attached :attachment
|
12
|
-
end
|
13
|
-
|
14
8
|
validates :attachment, attached: true, content_type: /\Aimage\/.*\z/
|
15
9
|
|
16
|
-
default_scope { includes(attachment_attachment: :blob) }
|
17
|
-
|
18
10
|
def self.styles
|
19
11
|
@styles ||= {
|
20
12
|
mini: '48x48>',
|
data/app/models/spree/image.rb
CHANGED
@@ -4,6 +4,8 @@ module Spree
|
|
4
4
|
include Rails.application.routes.url_helpers
|
5
5
|
include Spree::ImageMethods
|
6
6
|
|
7
|
+
after_commit :touch_product_variants, if: :should_touch_product_variants?, on: :update
|
8
|
+
|
7
9
|
# In Rails 5.x class constants are being undefined/redefined during the code reloading process
|
8
10
|
# in a rails development environment, after which the actual ruby objects stored in those class constants
|
9
11
|
# are no longer equal (subclass == self) what causes error ActiveRecord::SubclassNotFound
|
@@ -51,5 +53,20 @@ module Spree
|
|
51
53
|
def plp_url
|
52
54
|
generate_url(size: self.class.styles[:plp_and_carousel])
|
53
55
|
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def touch_product_variants
|
60
|
+
viewable.product.variants.touch_all
|
61
|
+
end
|
62
|
+
|
63
|
+
def should_touch_product_variants?
|
64
|
+
return false unless viewable.is_a?(Spree::Variant)
|
65
|
+
return false unless viewable.is_master?
|
66
|
+
return false unless viewable.product.has_variants?
|
67
|
+
return false unless saved_change_to_position?
|
68
|
+
|
69
|
+
true
|
70
|
+
end
|
54
71
|
end
|
55
72
|
end
|
@@ -5,6 +5,8 @@ module Spree
|
|
5
5
|
include Spree::Webhooks::HasWebhooks
|
6
6
|
end
|
7
7
|
|
8
|
+
attribute :quantity, :integer, default: 1
|
9
|
+
|
8
10
|
before_validation :ensure_valid_quantity
|
9
11
|
|
10
12
|
with_options inverse_of: :line_items do
|
@@ -13,7 +15,7 @@ module Spree
|
|
13
15
|
end
|
14
16
|
belongs_to :tax_category, -> { with_deleted }, class_name: 'Spree::TaxCategory'
|
15
17
|
|
16
|
-
has_one :product, through: :variant
|
18
|
+
has_one :product, -> { with_deleted }, class_name: 'Spree::Product', through: :variant
|
17
19
|
|
18
20
|
has_many :adjustments, as: :adjustable, dependent: :destroy
|
19
21
|
has_many :inventory_units, inverse_of: :line_item
|
@@ -27,7 +29,7 @@ module Spree
|
|
27
29
|
# numericality: :less_than_or_equal_to validation is due to the restriction at the database level
|
28
30
|
# https://github.com/spree/spree/issues/2695#issuecomment-143314161
|
29
31
|
validates :quantity, numericality: {
|
30
|
-
|
32
|
+
in: 0..DatabaseTypeUtilities.maximum_value_for(:integer),
|
31
33
|
only_integer: true, message: Spree.t('validation.must_be_int')
|
32
34
|
}
|
33
35
|
|
@@ -70,11 +72,7 @@ module Spree
|
|
70
72
|
def update_price
|
71
73
|
currency_price = variant.price_in(order.currency)
|
72
74
|
|
73
|
-
self.price = if currency_price.
|
74
|
-
currency_price.price_including_vat_for(tax_zone: tax_zone)
|
75
|
-
else
|
76
|
-
0
|
77
|
-
end
|
75
|
+
self.price = currency_price.price_including_vat_for(tax_zone: tax_zone) if currency_price.present?
|
78
76
|
end
|
79
77
|
|
80
78
|
def copy_tax_category
|
@@ -99,6 +97,13 @@ module Spree
|
|
99
97
|
amount + taxable_adjustment_total
|
100
98
|
end
|
101
99
|
|
100
|
+
# returns the total tax amount
|
101
|
+
#
|
102
|
+
# @return [BigDecimal]
|
103
|
+
def tax_total
|
104
|
+
included_tax_total + additional_tax_total
|
105
|
+
end
|
106
|
+
|
102
107
|
alias discounted_money display_discounted_amount
|
103
108
|
alias discounted_amount taxable_amount
|
104
109
|
|
@@ -117,6 +122,20 @@ module Spree
|
|
117
122
|
!sufficient_stock?
|
118
123
|
end
|
119
124
|
|
125
|
+
# returns true if any of the inventory units are shipped
|
126
|
+
#
|
127
|
+
# @return [Boolean]
|
128
|
+
def any_shipped?
|
129
|
+
inventory_units.any?(&:shipped?)
|
130
|
+
end
|
131
|
+
|
132
|
+
# returns true if all of the inventory units are shipped
|
133
|
+
#
|
134
|
+
# @return [Boolean]
|
135
|
+
def fully_shipped?
|
136
|
+
inventory_units.all?(&:shipped?)
|
137
|
+
end
|
138
|
+
|
120
139
|
def options=(options = {})
|
121
140
|
return unless options.present?
|
122
141
|
|
@@ -5,5 +5,9 @@ module Spree
|
|
5
5
|
|
6
6
|
validates :option_value, :variant, presence: true
|
7
7
|
validates :option_value_id, uniqueness: { scope: :variant_id }
|
8
|
+
|
9
|
+
scope :for_option_types, lambda { |option_types|
|
10
|
+
joins(:option_value).merge(Spree::OptionValue.where(option_types: option_types))
|
11
|
+
}
|
8
12
|
end
|
9
13
|
end
|
@@ -26,10 +26,10 @@ module Spree
|
|
26
26
|
def update_line_item_price!(line_item)
|
27
27
|
price = price_from_line_item(line_item)
|
28
28
|
|
29
|
-
if price
|
29
|
+
if price&.currency && price.amount
|
30
30
|
line_item.update!(currency: price.currency, price: price.amount)
|
31
31
|
else
|
32
|
-
|
32
|
+
line_item.destroy
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Spree
|
2
|
+
class Order < Spree::Base
|
3
|
+
module Webhooks
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
def send_order_canceled_webhook
|
7
|
+
# Implement your logic of sending cancale webhooks
|
8
|
+
end
|
9
|
+
|
10
|
+
def send_order_placed_webhook
|
11
|
+
# Implement your logic of sending order placed webhooks
|
12
|
+
end
|
13
|
+
|
14
|
+
def send_order_resumed_webhook
|
15
|
+
# Implement your logic of sending after resume webhooks
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/app/models/spree/order.rb
CHANGED
@@ -17,6 +17,7 @@ module Spree
|
|
17
17
|
include Spree::Order::StoreCredit
|
18
18
|
include Spree::Order::AddressBook
|
19
19
|
include Spree::Order::Emails
|
20
|
+
include Spree::Order::Webhooks
|
20
21
|
include Spree::Core::NumberGenerator.new(prefix: 'R')
|
21
22
|
include Spree::Core::TokenGenerator
|
22
23
|
|
@@ -25,9 +26,6 @@ module Spree
|
|
25
26
|
include Spree::SingleStoreResource
|
26
27
|
include Spree::MemoizedData
|
27
28
|
include Spree::Metadata
|
28
|
-
if defined?(Spree::Webhooks::HasWebhooks)
|
29
|
-
include Spree::Webhooks::HasWebhooks
|
30
|
-
end
|
31
29
|
if defined?(Spree::Security::Orders)
|
32
30
|
include Spree::Security::Orders
|
33
31
|
end
|
@@ -91,9 +89,9 @@ module Spree
|
|
91
89
|
belongs_to :user, optional: true
|
92
90
|
end
|
93
91
|
if Spree.admin_user_class
|
94
|
-
belongs_to :created_by, class_name: Spree.admin_user_class
|
95
|
-
belongs_to :approver, class_name: Spree.admin_user_class
|
96
|
-
belongs_to :canceler, class_name: Spree.admin_user_class
|
92
|
+
belongs_to :created_by, class_name: "::#{Spree.admin_user_class}", optional: true
|
93
|
+
belongs_to :approver, class_name: "::#{Spree.admin_user_class}", optional: true
|
94
|
+
belongs_to :canceler, class_name: "::#{Spree.admin_user_class}", optional: true
|
97
95
|
else
|
98
96
|
belongs_to :created_by, optional: true
|
99
97
|
belongs_to :approver, optional: true
|
@@ -401,6 +399,8 @@ module Spree
|
|
401
399
|
deliver_order_confirmation_email unless confirmation_delivered?
|
402
400
|
deliver_store_owner_order_notification_email if deliver_store_owner_order_notification_email?
|
403
401
|
|
402
|
+
send_order_placed_webhook
|
403
|
+
|
404
404
|
consider_risk
|
405
405
|
end
|
406
406
|
|
@@ -522,6 +522,14 @@ module Spree
|
|
522
522
|
self.shipments = Spree::Stock::Coordinator.new(self).shipments
|
523
523
|
end
|
524
524
|
|
525
|
+
# Returns the total weight of the inventory units in the order
|
526
|
+
# This is used to calculate the shipping rates for the order
|
527
|
+
#
|
528
|
+
# @return [BigDecimal] the total weight of the inventory units in the order
|
529
|
+
def total_weight
|
530
|
+
@total_weight ||= line_items.joins(:variant).includes(:variant).map { |li| li.variant.weight * li.quantity }.sum
|
531
|
+
end
|
532
|
+
|
525
533
|
def apply_free_shipping_promotions
|
526
534
|
Spree::PromotionHandler::FreeShipping.new(self).activate
|
527
535
|
shipments.each { |shipment| Spree::Adjustable::AdjustmentsUpdater.update(shipment) }
|
@@ -566,6 +574,7 @@ module Spree
|
|
566
574
|
def set_shipments_cost
|
567
575
|
shipments.each(&:update_amounts)
|
568
576
|
updater.update_shipment_total
|
577
|
+
updater.update_adjustment_total
|
569
578
|
persist_totals
|
570
579
|
end
|
571
580
|
|
@@ -726,11 +735,13 @@ module Spree
|
|
726
735
|
|
727
736
|
send_cancel_email
|
728
737
|
update_with_updater!
|
738
|
+
send_order_canceled_webhook
|
729
739
|
end
|
730
740
|
|
731
741
|
def after_resume
|
732
742
|
shipments.each(&:resume!)
|
733
743
|
consider_risk
|
744
|
+
send_order_resumed_webhook
|
734
745
|
end
|
735
746
|
|
736
747
|
def use_billing?
|
@@ -16,6 +16,7 @@ module Spree
|
|
16
16
|
end
|
17
17
|
|
18
18
|
set_user(user)
|
19
|
+
clear_addresses(other_order)
|
19
20
|
persist_merge
|
20
21
|
|
21
22
|
# So that the destroy doesn't take out line items which may have been re-assigned
|
@@ -39,6 +40,11 @@ module Spree
|
|
39
40
|
order.associate_user!(user) if !order.user && !user.blank?
|
40
41
|
end
|
41
42
|
|
43
|
+
def clear_addresses(other_order)
|
44
|
+
other_order.ship_address = nil
|
45
|
+
other_order.bill_address = nil
|
46
|
+
end
|
47
|
+
|
42
48
|
# The idea is the end developer can choose to override the merge
|
43
49
|
# to their own choosing. Default is merge with errors.
|
44
50
|
def handle_merge(current_line_item, other_order_line_item)
|