Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#161847] Rake tasks for adding new PriceGroups to ScheduleRules #3594

Merged
merged 11 commits into from
Jul 26, 2023
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ Because we use squash and merge, you should be able to see the changes by lookin
at the [commit log](https://github.com/tablexi/nucore-open/commits/master). However, we have begun keeping track of breaking changes
or optional rake tasks.

### Addition of `PriceGroupDiscount` ([#3397](https://github.com/tablexi/nucore-open/pull/3397), [#3594](https://github.com/tablexi/nucore-open/pull/3594))

Rather than one discount being set on a schedule rule, each global price group has its own discount (`PriceGroupDiscount`) for each schedule rule.

When transitioning a school to use `PriceGroupDiscount`s, the `schedule_rule:add_price_group_discounts` rake task should be run, which adds `PriceGroupDiscount`s for every global price group to every schedule rule.

When adding a new global price group, the `price_group:add_global_price_group` rake task should be run. This creates the global price group and sets up `PriceGroupDiscount`s for it for every schedule rule.

### Addition of `facility_tile_list: true` feature flag ([#3193](https://github.com/tablexi/nucore-open/pull/3193))

Schools that have set the feature flag `facility_tile_list: false` are not affected by this change.
Expand Down
54 changes: 54 additions & 0 deletions app/models/price_group.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ def self.external
globals.find_by(name: Settings.price_group.name.external)
end

# Create a global price group, if it does not exist, and setup all the
# schedule rules with price group discounts for the price group.
def self.setup_global(name:, is_internal: false, admin_editable: true, discount_percent: 0, display_order: nil)
price_group = find_or_create_global(name:, is_internal:, admin_editable:, display_order:)
price_group.setup_schedule_rules(discount_percent:)
price_group
end

def is_not_global?
!global?
end
Expand Down Expand Up @@ -78,4 +86,50 @@ def external?
!is_internal?
end

# Creates price group discounts for this price group, if they do not exist
def setup_schedule_rules(discount_percent: 0)
ScheduleRule.all.each do |schedule_rule|
schedule_price_groups = schedule_rule.price_group_discounts.map(&:price_group)

if schedule_price_groups.include? self
puts("price_group_discount for #{self} already exists for schedule rule #{schedule_rule.id}") unless Rails.env.test?
next
end

schedule_rule.price_group_discounts.create(
price_group: self,
discount_percent:
)

puts("Created price_group_discount for #{self} and schedule rule #{schedule_rule.id}") unless Rails.env.test?
end
end

private

# Find a global price group by name, or create it if it does not exist
def self.find_or_create_global(name:, display_order:, is_internal: false, admin_editable: true)
global_price_groups = PriceGroup.globals
found_price_group = global_price_groups.find_by(name:)

if found_price_group
puts("Global price group '#{name}' already exists.") unless Rails.env.test?

found_price_group
else
pg = PriceGroup.new(
name:,
is_internal:,
admin_editable:,
facility_id: nil,
display_order: display_order || (global_price_groups.count + 1)
)

pg.save(validate: false)

puts("Created global price group '#{name}'") unless Rails.env.test?

pg
end
end
end
18 changes: 11 additions & 7 deletions db/seeds.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,15 @@
PriceGroup.reset_column_information

[
PriceGroup.create_with(is_internal: true, admin_editable: false).find_or_initialize_by(name: Settings.price_group.name.base),
PriceGroup.create_with(is_internal: true, admin_editable: true).find_or_initialize_by(name: Settings.price_group.name.cancer_center),
PriceGroup.create_with(is_internal: false, admin_editable: false).find_or_initialize_by(name: Settings.price_group.name.external),
].each_with_index do |price_group, index|
next if price_group.name.blank? || price_group.persisted?
price_group.display_order = index + 1
price_group.save(validate: false)
{ name: Settings.price_group.name.base, is_internal: true, admin_editable: false },
{ name: Settings.price_group.name.cancer_center, is_internal: true, admin_editable: true },
{ name: Settings.price_group.name.external, is_internal: false, admin_editable: false },
].each do |pg_data|
next if pg_data[:name].blank?

PriceGroup.setup_global(
name: pg_data[:name],
is_internal: pg_data[:is_internal],
admin_editable: pg_data[:admin_editable]
)
end
12 changes: 3 additions & 9 deletions lib/tasks/demo_seed.rake
Original file line number Diff line number Diff line change
Expand Up @@ -51,24 +51,18 @@ namespace :demo do
end
end

order = 1
pgnu = pgex = nil

Settings.price_group.name.to_hash.each do |k, v|
price_group = PriceGroup.find_or_initialize_by(name: v) do |pg|
pg.is_internal = (k == :base || k == :cancer_center)
pg.display_order = order
end

price_group.save(validate: false) # override facility validator
price_group = PriceGroup.setup_global(
name: v, is_internal: (k == :base || k == :cancer_center)
)

if k == :base
pgnu = price_group
elsif k == :external
pgex = price_group
end

order += 1
end

fa = FacilityAccount.find_or_initialize_by(facility_id: facility.id) do |facility_account|
Expand Down
19 changes: 19 additions & 0 deletions lib/tasks/pirce_groups.rake
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

namespace :price_group do
# This creates a new global price group, if it does not exist, and adds
# a PriceGroupDiscount for it to every ScheduleRule. If the price group
# already exists, this will just add PriceGroupDiscounts for it to ScheduleRules
# that are missing then.
#
# rake price_group:add_global_price_group["new group",true,false,15]
desc "Create a new global price group and/or setup schedule rules for it"
task :add_global_price_group, [:name, :internal, :admin_editable, :discount] => :environment do |_t, args|
name = args[:name]
is_internal = args[:internal].casecmp("true").zero?
giladshanan marked this conversation as resolved.
Show resolved Hide resolved
admin_editable = args[:admin_editable].casecmp("true").zero?
discount_percent = args[:discount] || 0

PriceGroup.setup_global(name:, is_internal:, admin_editable:, discount_percent:)
end
end
5 changes: 4 additions & 1 deletion lib/tasks/schedule_rules.rake
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
# frozen_string_literal: true

namespace :schedule_rule do
desc "Adds PriceGroupDiscounts for global price groups to every schedule rule"
# This task is useful for switching a school over to PriceGroupDiscounts. If a
# school is already using price group discounts on all its schedule rules, this
# task will do nothing
desc "Adds PriceGroupDiscounts for existing global price groups to every schedule rule"
task add_price_group_discounts: :environment do |_t, _args|
price_groups = PriceGroup.globals

Expand Down
5 changes: 2 additions & 3 deletions spec/rails_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,8 @@
Affiliate.OTHER

# initialize price groups
@nupg = PriceGroup.find_or_create_by(name: Settings.price_group.name.base, is_internal: true, display_order: 1)
@nupg.save(validate: false)
PriceGroup.find_or_create_by(name: Settings.price_group.name.external, is_internal: false, display_order: 3).save(validate: false)
@nupg = PriceGroup.setup_global(name: Settings.price_group.name.base, is_internal: true, display_order: 1)
PriceGroup.setup_global(name: Settings.price_group.name.external, is_internal: false, display_order: 3)

# Because many specs rely on not crossing a fiscal year boundary we lock the
# time globally. Rails's `travel_to` helper does not work well with nesting, so
Expand Down