mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-26 20:56:48 +00:00
In the line below we filter them out in Ruby so it's a waste of
resources. The fundamental difference is that `#includes` and
`#references` results in LEFT JOINs, whereas `#joins` results in INNER
JOIN, and because there's a default scope on `deleted_at IS NULL`, these
are not included in the result set.
This however, requires us to move away from the current algorithm but
unfortunately we can't refactor it completely yet.
Before:
```sql
SELECT *
FROM "variant_overrides"
LEFT OUTER
JOIN "spree_variants"
ON "spree_variants"."id" = "variant_overrides"."variant_id"
AND "spree_variants"."deleted_at" IS NULL
LEFT OUTER
JOIN "spree_products"
ON "spree_products"."id" = "spree_variants"."product_id"
AND "spree_products"."deleted_at" IS NULL
WHERE "variant_overrides"."permission_revoked_at" IS NULL
AND "variant_overrides"."hub_id" IN (
SELECT "enterprises"."id"
FROM "enterprises"
INNER
JOIN "enterprise_roles"
ON "enterprise_roles"."enterprise_id" = "enterprises"."id"
WHERE (enterprise_roles.user_id = ?)
AND (sells != 'none')
ORDER BY name)
```
After:
```sql
SELECT "variant_overrides".*
FROM "variant_overrides"
INNER
JOIN "spree_variants"
ON "spree_variants"."id" = "variant_overrides"."variant_id"
AND "spree_variants"."deleted_at" IS NULL
INNER
JOIN "spree_products"
ON "spree_products"."id" = "spree_variants"."product_id"
AND "spree_products"."deleted_at" IS NULL
WHERE "variant_overrides"."permission_revoked_at" IS NULL
AND "variant_overrides"."hub_id" IN (
SELECT "enterprises"."id"
FROM "enterprises"
INNER
JOIN "enterprise_roles"
ON "enterprise_roles"."enterprise_id" = "enterprises"."id"
WHERE (enterprise_roles.user_id = ?)
AND (sells != 'none')
ORDER BY name)
```
This is covered in the test suite by
spec/controllers/admin/variant_overrides_controller_spec.rb:72. It keeps
passing so we're good to go.
81 lines
2.0 KiB
Ruby
81 lines
2.0 KiB
Ruby
class VariantOverride < ActiveRecord::Base
|
|
extend Spree::LocalizedNumber
|
|
include StockSettingsOverrideValidation
|
|
|
|
acts_as_taggable
|
|
|
|
belongs_to :hub, class_name: 'Enterprise'
|
|
belongs_to :variant, class_name: 'Spree::Variant'
|
|
|
|
validates :hub_id, presence: true
|
|
validates :variant_id, presence: true
|
|
# Default stock can be nil, indicating stock should not be reset or zero, meaning reset to zero. Need to ensure this can be set by the user.
|
|
validates :default_stock, numericality: { greater_than_or_equal_to: 0 }, allow_nil: true
|
|
|
|
default_scope { where(permission_revoked_at: nil) }
|
|
|
|
scope :for_hubs, lambda { |hubs|
|
|
where(hub_id: hubs)
|
|
}
|
|
|
|
scope :distinct_import_dates, lambda {
|
|
select('DISTINCT variant_overrides.import_date').
|
|
where('variant_overrides.import_date IS NOT NULL').
|
|
order('import_date DESC')
|
|
}
|
|
|
|
localize_number :price
|
|
|
|
def self.indexed(hub)
|
|
for_hubs(hub).preload(:variant).index_by(&:variant)
|
|
end
|
|
|
|
def stock_overridden?
|
|
# If count_on_hand is present, it means on_demand is false
|
|
# See StockSettingsOverrideValidation for details
|
|
count_on_hand.present?
|
|
end
|
|
|
|
def use_producer_stock_settings?
|
|
on_demand.nil?
|
|
end
|
|
|
|
def move_stock!(quantity)
|
|
unless stock_overridden?
|
|
Bugsnag.notify RuntimeError.new "Attempting to move stock of a VariantOverride without a count_on_hand specified."
|
|
return
|
|
end
|
|
|
|
if quantity > 0
|
|
increment! :count_on_hand, quantity
|
|
elsif quantity < 0
|
|
decrement! :count_on_hand, -quantity
|
|
end
|
|
end
|
|
|
|
def default_stock?
|
|
default_stock.present?
|
|
end
|
|
|
|
def reset_stock!
|
|
if resettable
|
|
if default_stock?
|
|
self.attributes = { on_demand: false, count_on_hand: default_stock }
|
|
save
|
|
else
|
|
Bugsnag.notify RuntimeError.new "Attempting to reset stock level for a variant with no default stock level."
|
|
end
|
|
end
|
|
self
|
|
end
|
|
|
|
def deletable?
|
|
price.blank? &&
|
|
count_on_hand.blank? &&
|
|
default_stock.blank? &&
|
|
resettable.blank? &&
|
|
sku.nil? &&
|
|
on_demand.nil?
|
|
end
|
|
end
|