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

Tech task: [#162316] Cross Core refactor #4431

Merged
merged 32 commits into from
Jul 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
3d0d6f8
Move Project model out of module and all related files
LeticiaErrandonea Jul 10, 2024
144224b
Move migrations
LeticiaErrandonea Jul 12, 2024
f92fcb2
Move Global search for Projects code
LeticiaErrandonea Jul 10, 2024
a20dda6
Remove ParamUpdater extension
LeticiaErrandonea Jul 10, 2024
1d0e1e4
Remove OrderDetailBatchUpdater extension
LeticiaErrandonea Jul 10, 2024
3f89827
Remove Reservation extension
LeticiaErrandonea Jul 10, 2024
e09bed6
Remove Facility extension
LeticiaErrandonea Jul 10, 2024
80fb3bf
Remove OrdersController extension
LeticiaErrandonea Jul 11, 2024
15122ec
Remove Reports extension
LeticiaErrandonea Jul 11, 2024
3c0894d
Remove projects ApplicationHelper
LeticiaErrandonea Jul 12, 2024
90255e3
Remove Order extension
LeticiaErrandonea Jul 12, 2024
bed5580
Remove OrderRowImporter extension
LeticiaErrandonea Jul 12, 2024
111df00
Remove OrderDetail extension
LeticiaErrandonea Jul 12, 2024
813e615
Remove code related to moved/deleted files
LeticiaErrandonea Jul 12, 2024
f9dff2e
Remove LinkCollection extension
LeticiaErrandonea Jul 16, 2024
feedd6f
Fix bug for project_params
LeticiaErrandonea Jul 16, 2024
9b6df1b
Move view templates into the app
giladshanan Jul 16, 2024
b62f702
Move export raw and ability logic
giladshanan Jul 16, 2024
b03b516
Move searcher logic
giladshanan Jul 16, 2024
8893ab2
Move controller
giladshanan Jul 16, 2024
8cb1692
Remove module
giladshanan Jul 16, 2024
eae100d
Routes
giladshanan Jul 16, 2024
bb7afd0
Update locales
giladshanan Jul 16, 2024
668e666
Move locales
giladshanan Jul 16, 2024
6108310
Move specs and delete engine config files
giladshanan Jul 16, 2024
9728947
Fix spec
giladshanan Jul 16, 2024
c74ffc2
Fix searcher attr_accessors
giladshanan Jul 16, 2024
301701c
Clean up
giladshanan Jul 17, 2024
5e71f6a
Update app/models/reports/export_raw.rb
giladshanan Jul 17, 2024
1afb2e5
Remove unnecessary change
LeticiaErrandonea Jul 17, 2024
54778ae
Move code to the relevant methods
LeticiaErrandonea Jul 17, 2024
e5b393d
Fix specs
LeticiaErrandonea Jul 17, 2024
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
1 change: 0 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ gem "c2po", path: "vendor/engines/c2po"
gem "dataprobe", path: "vendor/engines/dataprobe"
gem "ldap_authentication", path: "vendor/engines/ldap_authentication"
gem "saml_authentication", path: "vendor/engines/saml_authentication"
gem "projects", path: "vendor/engines/projects"
gem "sanger_sequencing", path: "vendor/engines/sanger_sequencing"
gem "secure_rooms", path: "vendor/engines/secure_rooms"
gem "split_accounts", path: "vendor/engines/split_accounts"
Expand Down
8 changes: 1 addition & 7 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,6 @@ PATH
devise_ldap_authenticatable (>= 0.8.6)
rails (>= 4.2)

PATH
remote: vendor/engines/projects
specs:
projects (0.0.1)

PATH
remote: vendor/engines/saml_authentication
specs:
Expand Down Expand Up @@ -791,7 +786,6 @@ DEPENDENCIES
parallel_tests
paranoia
prawn-rails
projects!
pry-byebug
pry-rails
puma
Expand Down Expand Up @@ -839,4 +833,4 @@ RUBY VERSION
ruby 3.3.0p0

BUNDLED WITH
2.4.20
2.5.8
1 change: 1 addition & 0 deletions app/controllers/global_search_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ def self.searcher_classes
GlobalSearch::OrderSearcher,
GlobalSearch::StatementSearcher,
GlobalSearch::ProductSearcher,
GlobalSearch::ProjectSearcher,
]
end

Expand Down
2 changes: 1 addition & 1 deletion app/controllers/orders_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def self.permitted_params
end

def self.permitted_acting_as_params
@permitted_acting_as_params ||= []
@permitted_acting_as_params ||= [:project_id]
end

def initialize
Expand Down
132 changes: 132 additions & 0 deletions app/controllers/projects_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# frozen_string_literal: true

class ProjectsController < ApplicationController
include SortableColumnController

admin_tab :all
before_action { @active_tab = action_name || "admin_projects" }

load_and_authorize_resource through: :current_facility, except: [:show, :edit, :update]
load_and_authorize_resource only: [:show, :edit, :update]

def index
raise ActionController::RoutingError, "Projects are only available in a facility context" unless current_facility

@search_form = ProjectsSearch::SearchForm.new(
params[:search],
defaults: {
current_facility_id: current_facility.id,
},
)

@search = ProjectsSearch::Searcher.search(nil, @search_form)
@projects = @search.projects.display_order

respond_to do |format|
format.html { @projects = @projects.paginate(page: params[:page]) }
end
end

def cross_core_orders
raise ActionController::RoutingError, "Projects are only available in a facility context" unless current_facility

@all_projects = @projects.display_order

order_details = cross_core_order_details

@search_form = TransactionSearch::SearchForm.new(
params[:search],
defaults: {
date_range_field: "ordered_at",
allowed_date_fields: ["ordered_at"],
cross_core_facilties: "other",
order_statuses: default_order_statuses(order_details),
current_facility_id: current_facility.id,
}
)

searchers = [
TransactionSearch::ProductSearcher,
TransactionSearch::OrderedForSearcher,
TransactionSearch::OrderStatusSearcher,
TransactionSearch::DateRangeSearcher,
ProjectsSearch::CrossCoreFacilitySearcher,
]

@search = TransactionSearch::Searcher.new(*searchers).search(order_details, @search_form)
@order_details = @search.order_details.includes(:order_status).reorder(sort_clause)

respond_to do |format|
format.html { @order_details = @order_details.paginate(page: params[:page]) }
end
end

def new
end

def backend?
true
end

def create
@project = current_facility.projects.new(project_params)
render action: :new unless save_project
end

def edit
end

def show
@order_details = @project.order_details.order(ordered_at: :desc).paginate(page: params[:page])
end

def update
@project.attributes = project_params
render action: :edit unless save_project
end

private

def default_order_statuses(order_details)
TransactionSearch::OrderStatusSearcher.new(order_details).options - [OrderStatus.canceled, OrderStatus.reconciled].map(&:id)
end

# Fetch ALL cross core order details related to the current facility
# Includes all order details from any cross core project that is associated with the current facility,
# and also all order details from any cross core project that includes an order from the current facility.
def cross_core_order_details
projects = Project.for_facility(current_facility)
OrderDetail.cross_core
.where(orders: { cross_core_project_id: projects })
end

def sort_lookup_hash
{
"facility" => "facilities.name",
"order_number" => ["order_details.order_id", "order_details.id"],
"ordered_at" => "order_details.ordered_at",
"status" => "order_statuses.name",
}
end

def project_params
params.require(:project).permit("active", "description", "name")
end

def save_project
if @project.save
flash[:notice] =
text(".#{action_name}.success", project_name: @project.name)
redirect_to facility_project_path(current_facility, @project)
end
end

def ability_resource
if ["show", "edit", "update"].include?(params[:action])
@project
else
current_facility
end
end

end
1 change: 1 addition & 0 deletions app/controllers/reports/general_reports_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ def self.reports
purchaser: ->(od) { format_username od.order.user },
price_group: ->(od) { od.price_policy ? od.price_policy.price_group.name : text("unassigned") },
assigned_to: ->(od) { od.assigned_user.presence ? format_username(od.assigned_user) : text("unassigned") },
project: ->(order_detail) { order_detail.project || " No Project" },
)
end

Expand Down
1 change: 1 addition & 0 deletions app/controllers/reports/instrument_reports_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ def self.reports
account: ->(reservation) { reservation.order_detail.account },
account_owner: ->(reservation) { format_username(reservation.order_detail.account.owner_user) },
purchaser: ->(reservation) { format_username(reservation.order_detail.user) },
project: ->(reservation) { reservation.order_detail.project || " No Project" },
)
end

Expand Down
4 changes: 2 additions & 2 deletions app/forms/add_to_order_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,8 @@ def add_to_order!
end

def create_cross_core_project_and_add_order!
Projects::Project.transaction do
@order_project ||= Projects::Project.new(
Project.transaction do
@order_project ||= Project.new(
name: "#{current_facility.abbreviation}-#{original_order.id}",
facility_id: current_facility.id
)
Expand Down
4 changes: 3 additions & 1 deletion app/forms/transaction_search/search_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ class SearchForm
attr_accessor :facilities, :accounts, :products, :account_owners,
:order_statuses, :statements, :date_ranges, :ordered_fors,
:account_types, :cross_cores, :cross_core_facilties,
:current_facility_id
:current_facility_id,
:projects,
:cross_core_facilties

def self.model_name
ActiveModel::Name.new(self, nil, "Search")
Expand Down
13 changes: 13 additions & 0 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ def warning_if_instrument_is_offline_or_partially_available(instrument)
end
end

def project_id_assignment_options(projects)
blank_project_options + options_from_collection_for_select(projects, :id, :name)
end

private

def show_currency(order_detail, method)
Expand All @@ -78,4 +82,13 @@ def responsive?
!admin_tab?
end

def blank_project_options
options_for_select(
[
[I18n.t("projects.shared.select_project.placeholder"), nil],
[I18n.t("projects.shared.select_project.unassign"), "unassign"],
],
)
end

end
3 changes: 2 additions & 1 deletion app/lib/ability.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def initialize(user, resource, controller = nil)
end

ability_extender.extend(user, resource)
Projects::AbilityExtension.new(self).extend(user, resource)
end


Expand All @@ -55,7 +56,7 @@ def administrator_abilities(user, resource)
unless user.account_manager?
# TODO: Refactor
# We think this is here to keep the Users tab visible. See LinkCollection#admin_users.
cannot :manage, User unless resource.is_a?(Facility) || resource.is_a?(Projects::Project)
cannot :manage, User unless resource.is_a?(Facility) || resource.is_a?(Project)
if SettingsHelper.feature_off?(:create_users)
cannot([:edit, :update], User)
end
Expand Down
1 change: 1 addition & 0 deletions app/models/facility.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class Facility < ApplicationRecord
has_many :users, -> { distinct }, through: :user_roles
has_many :reservations, through: :instruments
has_many :product_display_groups
has_many :projects, inverse_of: :facility, dependent: :destroy # Though Facilities cannot be destroyed

validates_presence_of :name, :short_description, :abbreviation
validate_url_name :url_name
Expand Down
9 changes: 8 additions & 1 deletion app/models/order.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class Order < ApplicationRecord
belongs_to :account
belongs_to :facility
belongs_to :order_import
belongs_to :cross_core_project, class_name: "Projects::Project"
belongs_to :cross_core_project, class_name: "Project"
has_many :order_details, inverse_of: :order, dependent: :destroy

validates_presence_of :user_id, :created_by
Expand All @@ -22,6 +22,8 @@ class Order < ApplicationRecord
# Used to allow validating order imports against the fulfillment date instead of the current time
attr_reader :import_fulfillment_date

attr_reader :project_id

def cross_core_project
return nil unless SettingsHelper.feature_on?(:cross_core_projects)

Expand Down Expand Up @@ -216,6 +218,11 @@ def ordered_on_behalf_of?
user_id != created_by
end

def project_id=(project_id)
@project_id = project_id
order_details.each { |order_detail| order_detail.project_id = project_id }
end

private

# If we update the account of the order, update the account of
Expand Down
15 changes: 14 additions & 1 deletion app/models/order_detail.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ def set_problem_order
belongs_to :bundle, foreign_key: "bundle_product_id"
belongs_to :canceled_by_user, foreign_key: :canceled_by, class_name: "User"
belongs_to :problem_resolved_by, class_name: "User"
belongs_to :project, class_name: "Project", foreign_key: :project_id, inverse_of: :order_details
has_one :reservation, inverse_of: :order_detail
# for some reason, dependent: :delete on reservation isn't working with paranoia, hitting foreign key constraints
before_destroy { reservation.try(:really_destroy!) }
Expand All @@ -72,7 +73,7 @@ def set_problem_order
# allow access to the vestal data.
# once that data is no longer needed, this line and the
# associated class can be removed
has_many :vestal_versions, as: :versioned
has_many :vestal_versions, as: :versioned

delegate :edit_url, to: :external_service_receiver, allow_nil: true
delegate :in_cart?, :facility, :user, to: :order # user is the ordered_for user, not ordered_by user
Expand All @@ -81,6 +82,7 @@ def set_problem_order
delegate :ordered_on_behalf_of?, to: :order
delegate :price_group, to: :price_policy, allow_nil: true
delegate :reference, to: :journal, prefix: true, allow_nil: true
delegate :projects, to: :facility, prefix: true

def estimated_price_group
estimated_price_policy.try(:price_group)
Expand Down Expand Up @@ -113,6 +115,7 @@ def journal_or_statement_date
validates_length_of :note, maximum: 1000, allow_blank: true, allow_nil: true
validate :valid_manual_fulfilled_at
validates :price_change_reason, presence: true, length: { minimum: 10, allow_blank: true }, if: :pricing_note_required?
validate :project_must_be_active, if: :project_id_changed?

def actual_costs_match_calculated?
dup_od = dup
Expand Down Expand Up @@ -986,6 +989,10 @@ def cross_core_for_originating_facility?
order.cross_core_project.present? && order.cross_core_project.facility_id != order.facility_id
end

def selectable_projects
(facility_projects.active.display_order + [project]).uniq.compact
end

private

# Is there enough information to move an associated order to complete/problem?
Expand Down Expand Up @@ -1084,4 +1091,10 @@ def pricing_note_required?
def update_billable_minutes_on_reservation
reservation.update_billable_minutes
end

def project_must_be_active
if project.present? && !project.active?
errors.add(:project_id, :project_is_inactive)
end
end
end
Loading
Loading