Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 0 additions & 26 deletions app/controllers/spree/admin/products_controller_decorator.rb

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
module Spree
module Admin
module SpreePriceBooks
module ProductsControllerDecorator
def variant_prices
id = session[:current_price_book_id]
session.delete(:current_price_book_id)

@current_price_book = id.present? ? PriceBook.find(id) : PriceBook.default

# need every variant/price(for the current price book) pair
# I had to do this ridiculous sort to get the master first since the scope orders by position,
# but for some reason the position is screwed up for master (it's not first)
@variants = @product.variants_including_master.partition {|v| v.is_master?}.flatten

@prices = {}

@variants.each do |variant|
@prices[variant.id] = variant.prices.detect {|price| price.price_book_id == @current_price_book.id} # possibly nil
end

@price_books = PriceBook.order('priority')
@default_price_book = @price_books.detect {|pb| pb.default?}
end
end
end
end
end

Spree::Admin::ProductsController.prepend Spree::Admin::SpreePriceBooks::ProductsControllerDecorator
7 changes: 0 additions & 7 deletions app/helpers/spree/base_helper_decorator.rb

This file was deleted.

11 changes: 11 additions & 0 deletions app/helpers/spree/spree_price_books/base_helper_decorator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module Spree
module SpreePriceBooks
module BaseHelperDecorator
def display_price(product_or_variant)
product_or_variant.price_in(current_currency, current_store.id, spree_current_user.try(:price_book_role_ids)).display_price.to_html
end
end
end
end

Spree::BaseHelper.prepend Spree::SpreePriceBooks::BaseHelperDecorator
33 changes: 0 additions & 33 deletions app/models/spree/order/currency_updater_decorator.rb

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
module Spree
class Order
module SpreePriceBooks
module CurrencyUpdaterDecorator
# Returns the price object from given item
def list_price_from_line_item(line_item)
line_item.variant.list_price_in(currency, store_id, user.try(:price_book_role_ids))
end

# Returns the price object from given item
def price_from_line_item(line_item)
line_item.variant.price_in(currency, store_id, user.try(:price_book_role_ids))
end

# Updates price from given line item
def update_line_item_price!(line_item)
list_price = list_price_from_line_item(line_item)
price = price_from_line_item(line_item)

if price
line_item.update_attributes!(
currency: price.currency,
list_price: list_price.price,
price: price.price
)
else
raise RuntimeError, "no #{currency} price found for #{line_item.product.name} (#{line_item.variant.sku})"
end
end
end
end
end
end

Spree::Order::CurrencyUpdater.prepend Spree::Order::SpreePriceBooks::CurrencyUpdaterDecorator
53 changes: 0 additions & 53 deletions app/models/spree/price_decorator.rb

This file was deleted.

6 changes: 0 additions & 6 deletions app/models/spree/role_decorator.rb

This file was deleted.

55 changes: 55 additions & 0 deletions app/models/spree/spree_price_books/price_decorator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
module Spree::SpreePriceBooks::PriceDecorator
def self.prepended(base)
base.belongs_to :price_book

base.has_many :store_price_books, through: :price_book

base.validate :ensure_proper_currency
base.validates :price_book_id, presence: true

base.before_validation :ensure_price_book

base.after_create :populate_children
base.after_update :update_children

base.delegate :product, to: :variant

base.scope :by_currency, -> (currency_iso) { where(currency: currency_iso) }
base.scope :by_role, -> (role_ids) { prioritized.where(spree_price_books: { role_id: role_ids }) }
base.scope :by_store, -> (store_id) { joins(:store_price_books).where(spree_store_price_books: { store_id: store_id }) }
base.scope :list, -> { prioritized.where(spree_price_books: { discount: false }) }
base.scope :prioritized, -> { includes(:price_book).order('spree_price_books.priority DESC, spree_prices.amount ASC') }
end

private

def ensure_price_book
self.price_book ||= Spree::PriceBook.default
end

def ensure_proper_currency
unless currency == price_book.currency
errors.add(:currency, :match_price_book)
end
end

def populate_children
price_book.children.each do |book|
if price = book.prices.find_by_variant_id(self.variant_id)
price.update_attribute :amount, self.amount * book.price_adjustment_factor
else
book.prices.create amount: (self.amount * book.price_adjustment_factor), currency: book.currency, variant_id: self.variant_id
end
end
end

def update_children
price_book.children.each do |book|
if price = book.prices.find_by_variant_id(self.variant_id)
price.update_attribute :amount, self.amount * book.price_adjustment_factor
end
end
end
end

Spree::Price.prepend Spree::SpreePriceBooks::PriceDecorator
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
Spree::Product.class_eval do

has_many :price_books, through: :master
module Spree::SpreePriceBooks::ProductDecorator
def self.prepended(base)
base.has_many :price_books, through: :master
end

def master_price_for(price_book)
Spree::Price.where(
Expand All @@ -13,5 +14,6 @@ def display_master_price_for(price_book)
price = master_price_for(price_book)
Spree::Money.new(price.amount, currency: price_book.currency)
end

end

Spree::Product.prepend Spree::SpreePriceBooks::ProductDecorator
8 changes: 8 additions & 0 deletions app/models/spree/spree_price_books/role_decorator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module Spree::SpreePriceBooks::RoleDecorator
def self.prepended(base)
base.has_many :price_books
base.scope :with_price_book, -> { where(id: Spree::PriceBook.pluck(:role_id).uniq) }
end
end

Spree::Role.prepend Spree::SpreePriceBooks::RoleDecorator
12 changes: 12 additions & 0 deletions app/models/spree/spree_price_books/store_decorator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module Spree::SpreePriceBooks::StoreDecorator
def self.prepended(base)
base.has_many :price_books, -> {
select("DISTINCT (#{table_name}.id), #{table_name}.*, #{Spree::StorePriceBook.table_name}.priority").
order("#{Spree::StorePriceBook.table_name}.priority DESC")
}, through: :store_price_books

base.has_many :store_price_books
end
end

Spree::Store.prepend Spree::SpreePriceBooks::StoreDecorator
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Spree.user_class.class_eval do

module Spree::SpreePriceBooks::UserDecorator
# When prices are determined based on the user role we must also include nil.
def price_book_role_ids
[nil, spree_roles.pluck(:id)].flatten
end

end

Spree::user_class.prepend Spree::SpreePriceBooks::UserDecorator
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
Spree::Variant.class_eval do

## Associations

has_one :default_price,
-> { where currency: Spree::Config[:currency], price_book_id: Spree::PriceBook.default.id },
class_name: 'Spree::Price',
dependent: :destroy

has_many :prices,
class_name: 'Spree::Price',
dependent: :destroy,
inverse_of: :variant

has_many :price_books, -> { active.order('spree_prices.amount ASC, spree_price_books.priority DESC') }, through: :prices

## Class Methods

## Instance Methods
module Spree::SpreePriceBooks::VariantDecorator
def self.prepended(base)
base.has_one :default_price,
-> { where currency: Spree::Config[:currency], price_book_id: Spree::PriceBook.default.id },
class_name: 'Spree::Price',
dependent: :destroy
Comment on lines +4 to +6
Copy link

Copilot AI Oct 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The association definition spans multiple lines but uses inconsistent indentation. Consider aligning the lambda block parameters consistently with the association declaration.

Suggested change
-> { where currency: Spree::Config[:currency], price_book_id: Spree::PriceBook.default.id },
class_name: 'Spree::Price',
dependent: :destroy
-> { where currency: Spree::Config[:currency], price_book_id: Spree::PriceBook.default.id },
class_name: 'Spree::Price',
dependent: :destroy

Copilot uses AI. Check for mistakes.

base.has_many :prices,
Copy link

Copilot AI Oct 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Similar to the previous association, the multi-line association definition should maintain consistent indentation for better readability.

Copilot uses AI. Check for mistakes.
class_name: 'Spree::Price',
dependent: :destroy,
inverse_of: :variant

base.has_many :price_books, -> { active.order('spree_prices.amount ASC, spree_price_books.priority DESC') }, through: :prices
end

def display_list_price(currency = Spree::Config[:currency], store_id = Spree::Store.default.id, role_ids = nil)
lp = list_price_in(currency, store_id)
Expand All @@ -39,5 +34,6 @@ def price_in(currency = Spree::Config[:currency], store_id = Spree::Store.defaul
prices.by_currency(currency).by_role(role_ids).first
end
end

end

Spree::Variant.prepend Spree::SpreePriceBooks::VariantDecorator
10 changes: 0 additions & 10 deletions app/models/spree/store_decorator.rb

This file was deleted.

6 changes: 4 additions & 2 deletions lib/spree_price_books/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ def self.activate

config.to_prepare &method(:activate).to_proc

initializer "spree_active_shipping.register.calculators" do |app|
app.config.spree.calculators.shipping_methods << Spree::Calculator::Shipping::FlatMultiCurrencyRate
initializer "spree_price_books.register.calculators", after: "spree.register.calculators" do |app|
Rails.application.config.after_initialize do
app.config.spree.calculators.shipping_methods << Spree::Calculator::Shipping::FlatMultiCurrencyRate
end
end
end
end