-
Notifications
You must be signed in to change notification settings - Fork 29
Expand file tree
/
Copy pathsearcher.rb
More file actions
126 lines (102 loc) · 3.56 KB
/
searcher.rb
File metadata and controls
126 lines (102 loc) · 3.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# frozen_string_literal: true
module TransactionSearch
class Searcher
# Do not modify this array directly. Use `TransactionSearch.register` instead.
# There is some additional setup that needs to happen (adding an attr_accessor
# to SearchForm) that `register` handles.
cattr_accessor(:default_searchers) do
[
TransactionSearch::FacilitySearcher,
TransactionSearch::AccountSearcher,
TransactionSearch::AccountTypeSearcher,
TransactionSearch::ProductSearcher,
TransactionSearch::AccountOwnerSearcher,
TransactionSearch::PriceGroupSearcher,
TransactionSearch::OrderedForSearcher,
TransactionSearch::OrderStatusSearcher,
TransactionSearch::DateRangeSearcher,
TransactionSearch::CrossCoreSearcher,
ProjectsSearch::ProjectSearcher,
]
end
# Prefer `TransactionSearch.register_optimizer` rather than modifying this
# directly in order to maintain API consistency with `default_searchers`.
cattr_accessor(:optimizers) do
[
TransactionSearch::NPlusOneOptimizer,
]
end
# Initially all searchers in default_searchers
# are enabled
cattr_accessor(:default_config) do
{
facilities: false,
price_groups: SettingsHelper.feature_on?(:billing_table_price_groups),
}
end
# Shorthand method if you only want the default searchers
def self.search(order_details, params)
new.search(order_details, params)
end
# Expects an array of `TransactionSearch::BaseSearcher`s
def initialize(*searchers, **kwargs)
searchers_config = default_config.merge(kwargs)
@searchers_config = searchers_config
@searchers =
searchers.presence ||
default_searchers.filter do |searcher_class|
searchers_config.fetch(searcher_class.key.to_sym, true)
end
end
def search(order_details, params)
order_details = add_global_optimizations(order_details)
@searchers.reduce(Results.new(order_details)) do |results, searcher_class|
searcher_config = searcher_config(searcher_class.key.to_sym)
searcher = searcher_class.new(
results.order_details,
params[:current_facility_id],
**searcher_config,
)
search_params = params[searcher_class.key.to_sym]
search_params = Array(search_params).reject(&:blank?) unless searcher.multipart?
# Options should not be restricted, they should search over the full order details
option_searcher = searcher_class.new(order_details, **searcher_config)
Results.new(
searcher.search(search_params),
results.options + [option_searcher],
)
end
end
private
def add_global_optimizations(order_details)
optimizers.reduce(order_details) do |current, optimizer|
optimizer.new(current).optimize
end
end
def searcher_config(searcher_key)
value = @searchers_config[searcher_key]
if value.is_a?(Hash)
value
else
{}
end
end
class Results
attr_reader :order_details
# Return an array of options for a given key
delegate :[], to: :to_options_by_searcher
def initialize(order_details, search_options = [])
@order_details = order_details
@search_options = search_options.freeze
end
def options
@search_options.dup
end
def to_options_by_searcher
@to_h ||= options.to_h do |searcher|
[searcher.key, searcher.options]
end
end
end
end
end