bmc 1.6.2 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -0
  3. data/app/controllers/bmc/filters_controller.rb +3 -3
  4. data/app/controllers/concerns/bmc/api_controller_concern.rb +1 -1
  5. data/app/controllers/concerns/bmc/back_url_concern.rb +1 -2
  6. data/app/emails/bmc/email.rb +14 -17
  7. data/app/filters/bmc/filter/by_date.rb +1 -1
  8. data/app/filters/bmc/filter/by_date_or_datetime_period.rb +1 -1
  9. data/app/filters/bmc/filter/by_key_values.rb +1 -1
  10. data/app/filters/bmc/filter.rb +8 -2
  11. data/app/helpers/bmc/all_helpers.rb +1 -1
  12. data/app/helpers/bmc/bootstrap_helper.rb +8 -14
  13. data/app/helpers/bmc/button_helper.rb +26 -27
  14. data/app/helpers/bmc/filters_helper.rb +9 -9
  15. data/app/helpers/bmc/pagination_helper.rb +2 -2
  16. data/app/helpers/bmc/routes_helper.rb +4 -4
  17. data/app/helpers/bmc/sorting_helper.rb +2 -4
  18. data/app/helpers/bmc/text_helper.rb +18 -18
  19. data/app/libs/bmc/collection_update.rb +1 -1
  20. data/app/libs/bmc/mini_model_serializer/serializer.rb +3 -17
  21. data/app/libs/bmc/token_generator.rb +1 -3
  22. data/app/models/concerns/bmc/active_record_uuid_concern.rb +1 -3
  23. data/app/models/concerns/bmc/default_values_concern.rb +1 -2
  24. data/app/models/concerns/bmc/model_i18n.rb +5 -9
  25. data/app/models/concerns/bmc/search.rb +7 -7
  26. data/app/serializers/bmc/serializers/base.rb +3 -2
  27. data/app/serializers/bmc/serializers/xlsx.rb +2 -2
  28. data/app/sms/bmc/sms/application_sms.rb +5 -5
  29. data/app/sms/bmc/sms/strategies/amazon.rb +13 -13
  30. data/app/sms/bmc/sms/strategies/sendinblue.rb +8 -8
  31. data/app/sorters/bmc/sorter.rb +5 -5
  32. data/lib/bmc/active_model_custom_error_messages.rb +2 -0
  33. data/lib/bmc/active_model_type_cast.rb +5 -4
  34. data/lib/bmc/config.rb +1 -5
  35. data/lib/bmc/engine.rb +0 -3
  36. data/lib/bmc/errors_middleware.rb +5 -9
  37. data/lib/bmc/form_back_url.rb +5 -5
  38. data/lib/bmc/version.rb +1 -1
  39. metadata +9 -55
  40. data/app/libs/bmc/monkey.rb +0 -39
  41. data/app/models/concerns/bmc/polymorphic_id.rb +0 -37
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8507815d52d0ef0d3ae7ceb8013953ea235cddb3ac7efaba2c817e32187d0ac7
4
- data.tar.gz: 97b8bd28ef52423506015e77a1332443ce9e25f47f6b177418de366e46600e19
3
+ metadata.gz: 1f8f87fc4a9d9e8b97569d9d93cbfff1f2441406a71c8deda7999ba4bc6a5662
4
+ data.tar.gz: d613591c88f3093b9d749d4f01066ba4a8feff4cabcd5c989593daebc2394d5c
5
5
  SHA512:
6
- metadata.gz: 37f284b2e4103367199856fb20017b509eb7834f0e57e73721a05dede3750df48d3e843fcbd1b3870f3fc1280eb169425bac011c9ef5c70708d004abaa3f5265
7
- data.tar.gz: f5f269c338dfc62ae11e9c7db9b42e5d6afa8e475ea10e707cac85f428a3cb6ac7def5018e4914b2c147b88d1f91aafe47aae8de95dc074a03bc1a92587873fa
6
+ metadata.gz: 5e5560f60e2bb384459a56ac84c442e9db7e38901d2c451873ffb4955c25a6cced4a024011b3df705153a188d9ad9cb6cf454a7cdc63aba6390d721cec1c05e0
7
+ data.tar.gz: 6a9af20cd5d6abbe28924a4511d3ba701628432f158598ba65f4217a8ba035d200fc198818213a26a37304a4b9b2b141f041cc83cff29c2edd321548ec634be1
data/CHANGELOG.md CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  ## Next version
4
4
 
5
+ ## v1.8.0
6
+ - Rails 8.1
7
+ - Remove awesome_print dependency
8
+ - Remove pry-rails dependency
9
+ - Remove tapenade dependency
10
+
11
+ ## v1.7.0
12
+ - Rails 8.0
13
+ - Ruby 3.3.0 minimum
14
+ - Fix to `Filter#actives_count` to handle `[""]` value
15
+ - Fix Rubocop
16
+
5
17
  ## v1.6.2
6
18
  - `ApiControllerConcern` change
7
19
 
@@ -15,9 +15,9 @@ class BMC::FiltersController < BMC::ApplicationController
15
15
  filters.merge! params.fetch(:filters, {}).permit!.to_h
16
16
 
17
17
  cookies[:filters] = {
18
- :value => JSON.dump(filters),
19
- :expires => 1.year.from_now,
20
- :path => "/",
18
+ value: JSON.dump(filters),
19
+ expires: 1.year.from_now,
20
+ path: "/",
21
21
  }
22
22
 
23
23
  redirect_to back_url
@@ -20,7 +20,7 @@ module BMC::ApiControllerConcern
20
20
  options[:object_key] || any_object.model_name.singular => any_object,
21
21
  }
22
22
  elsif any_object.is_a?(String)
23
- json = {error: any_object}
23
+ json = { error: any_object }
24
24
  else
25
25
  json = any_object
26
26
  end
@@ -3,8 +3,7 @@ module BMC::BackUrlConcern
3
3
 
4
4
  private
5
5
 
6
- def default_back_url
7
- end
6
+ def default_back_url; end
8
7
 
9
8
  def back_url
10
9
  url = [
@@ -37,13 +37,13 @@ class BMC::Email
37
37
 
38
38
  def data
39
39
  {
40
- :from => from,
41
- :reply_to => reply_to,
42
- :to => to,
43
- :cc => cc,
44
- :subject => subject,
45
- :body => body,
46
- :attachments => attachments,
40
+ from: from,
41
+ reply_to: reply_to,
42
+ to: to,
43
+ cc: cc,
44
+ subject: subject,
45
+ body: body,
46
+ attachments: attachments,
47
47
  }
48
48
  end
49
49
 
@@ -71,24 +71,19 @@ class BMC::Email
71
71
  self.attachments ||= default_attachments
72
72
  end
73
73
 
74
- def default_from
75
- end
74
+ def default_from; end
76
75
 
77
76
  def default_reply_to
78
77
  "#{current_user} <#{current_user.email}>" if current_user
79
78
  end
80
79
 
81
- def default_to
82
- end
80
+ def default_to; end
83
81
 
84
- def default_cc
85
- end
82
+ def default_cc; end
86
83
 
87
- def default_subject
88
- end
84
+ def default_subject; end
89
85
 
90
- def default_body
91
- end
86
+ def default_body; end
92
87
 
93
88
  def default_attachments
94
89
  {}
@@ -106,8 +101,10 @@ class BMC::Email
106
101
 
107
102
  string = public_send(attr).to_s
108
103
  return if string.blank?
104
+
109
105
  addrs = Mail.new(to: string).to_addrs
110
106
  return true if addrs.any? && addrs.all? { |addr| URI::MailTo::EMAIL_REGEXP.match?(addr) }
107
+
111
108
  errors.add(attr, :invalid)
112
109
  end
113
110
  end
@@ -1,6 +1,6 @@
1
1
  class BMC::Filter::ByDate < BMC::Filter::ByKeyValue
2
2
  def call(query, value)
3
3
  value = Date.parse(value)
4
- super(query, value)
4
+ super
5
5
  end
6
6
  end
@@ -7,7 +7,7 @@ class BMC::Filter::ByDateOrDatetimePeriod < BMC::Filter::ByKeyValue
7
7
  super
8
8
  end
9
9
 
10
- def call(query, value) # rubocop:disable Metrics/MethodLength
10
+ def call(query, value)
11
11
  value = value.to_s
12
12
 
13
13
  if value == "today"
@@ -1,7 +1,7 @@
1
1
  class BMC::Filter::ByKeyValues < BMC::Filter::ByKeyValue
2
2
  def call(query, value)
3
3
  value = value.split if value.is_a?(String)
4
- value = value.select(&:present?)
4
+ value = value.compact_blank
5
5
 
6
6
  return query if value == ["all"]
7
7
 
@@ -1,7 +1,7 @@
1
1
  class BMC::Filter
2
2
  include ActiveModel::Model
3
3
 
4
- STRATEGIES = {}
4
+ STRATEGIES = {}.freeze
5
5
 
6
6
  attr_reader :values, :options
7
7
 
@@ -39,7 +39,13 @@ class BMC::Filter
39
39
  end
40
40
 
41
41
  def actives_count
42
- values.count { |k, v| strategies.key?(k) && v.present? }
42
+ values.count do |k, v|
43
+ next false unless strategies.key?(k)
44
+ next false if v.blank?
45
+ next false if v.respond_to?(:compact_blank) && v.compact_blank.none?
46
+
47
+ true
48
+ end
43
49
  end
44
50
 
45
51
  def any?
@@ -11,5 +11,5 @@ module BMC::AllHelpers
11
11
  include BMC::SortingHelper
12
12
  include BMC::TextHelper
13
13
 
14
- extend self
14
+ extend self # rubocop:disable Style/ModuleFunction
15
15
  end
@@ -1,18 +1,16 @@
1
1
  module BMC::BootstrapHelper
2
2
  class << self
3
- attr_writer :card_classes
3
+ attr_writer :card_classes, :bootstrap_version
4
4
 
5
5
  def card_classes
6
6
  @card_classes ||= {
7
- :card => "card",
8
- :header => "card-header",
9
- :body => "card-body",
10
- :footer => "card-footer",
7
+ card: "card",
8
+ header: "card-header",
9
+ body: "card-body",
10
+ footer: "card-footer",
11
11
  }
12
12
  end
13
13
 
14
- attr_writer :bootstrap_version
15
-
16
14
  def bootstrap_version
17
15
  @bootstrap_version ||= Bootstrap::VERSION[0]
18
16
  end
@@ -28,7 +26,7 @@ module BMC::BootstrapHelper
28
26
  end
29
27
  end
30
28
 
31
- def bs_card( # rubocop:disable Metrics/ParameterLists
29
+ def bs_card(
32
30
  header: nil,
33
31
  body: true,
34
32
  footer: nil,
@@ -48,9 +46,7 @@ module BMC::BootstrapHelper
48
46
  body_classes = ([global_classes[:body]] + body_class.to_s.split).compact.sort
49
47
  footer_classes = ([global_classes[:footer]] + footer_class.to_s.split).compact.sort
50
48
 
51
- if header
52
- header_html = content_tag(header_tag, class: header_classes) { header }
53
- end
49
+ header_html = content_tag(header_tag, class: header_classes) { header } if header
54
50
 
55
51
  if body
56
52
  body_html = content_tag(body_tag, class: body_classes) { capture(&block) }
@@ -58,9 +54,7 @@ module BMC::BootstrapHelper
58
54
  body_html = capture(&block)
59
55
  end
60
56
 
61
- if footer
62
- footer_html = content_tag(footer_tag, class: footer_classes) { footer }
63
- end
57
+ footer_html = content_tag(footer_tag, class: footer_classes) { footer } if footer
64
58
 
65
59
  content_tag(card_tag, class: card_classes) do
66
60
  [header_html, body_html, footer_html].compact.sum("".html_safe)
@@ -19,12 +19,11 @@ module BMC::ButtonHelper
19
19
  end
20
20
  end
21
21
 
22
- def bs_button( # rubocop:disable Metrics/ParameterLists
22
+ def bs_button(
23
23
  url,
24
- method: :get,
24
+ icon:, method: :get,
25
25
  confirm: nil,
26
26
  text: nil,
27
- icon:,
28
27
  action: nil,
29
28
  title: text,
30
29
  btn_size: BMC::ButtonHelper.default_size,
@@ -73,9 +72,9 @@ module BMC::ButtonHelper
73
72
 
74
73
  def new_button(url = url_for(action: :new), **options)
75
74
  options = {
76
- :icon => :plus,
77
- :action => :new,
78
- :btn_style => :success,
75
+ icon: :plus,
76
+ action: :new,
77
+ btn_style: :success,
79
78
  }.merge(options)
80
79
 
81
80
  bs_button(url, **options)
@@ -83,8 +82,8 @@ module BMC::ButtonHelper
83
82
 
84
83
  def read_button(url, **options)
85
84
  options = {
86
- :icon => :info_circle,
87
- :action => :read,
85
+ icon: :info_circle,
86
+ action: :read,
88
87
  }.merge(options)
89
88
 
90
89
  bs_button(url, **options)
@@ -92,8 +91,8 @@ module BMC::ButtonHelper
92
91
 
93
92
  def edit_button(url, **options)
94
93
  options = {
95
- :icon => :pencil_alt,
96
- :action => :edit,
94
+ icon: :pencil_alt,
95
+ action: :edit,
97
96
  }.merge(options)
98
97
 
99
98
  bs_button(url, **options)
@@ -101,10 +100,10 @@ module BMC::ButtonHelper
101
100
 
102
101
  def delete_button(url, **options)
103
102
  options = {
104
- :icon => :trash,
105
- :action => :delete,
106
- :btn_style => :danger,
107
- :method => :delete,
103
+ icon: :trash,
104
+ action: :delete,
105
+ btn_style: :danger,
106
+ method: :delete,
108
107
  }.merge(options)
109
108
 
110
109
  bs_button(url, **options)
@@ -112,9 +111,9 @@ module BMC::ButtonHelper
112
111
 
113
112
  def print_button(**options)
114
113
  options = {
115
- :icon => :print,
116
- :action => :print,
117
- :onclick => "print(); return false;",
114
+ icon: :print,
115
+ action: :print,
116
+ onclick: "print(); return false;",
118
117
  }.merge(options)
119
118
 
120
119
  bs_button("#", **options)
@@ -122,9 +121,9 @@ module BMC::ButtonHelper
122
121
 
123
122
  def download_button(url, **options)
124
123
  options = {
125
- :icon => :cloud_download_alt,
126
- :action => :download,
127
- :target => :_blank,
124
+ icon: :cloud_download_alt,
125
+ action: :download,
126
+ target: :_blank,
128
127
  }.merge(options)
129
128
 
130
129
  bs_button(url, **options)
@@ -140,9 +139,9 @@ module BMC::ButtonHelper
140
139
  end
141
140
 
142
141
  options = {
143
- :icon => :download,
144
- :action => :export,
145
- :text => text,
142
+ icon: :download,
143
+ action: :export,
144
+ text: text,
146
145
  }.merge(options)
147
146
 
148
147
  download_button(url, **options)
@@ -150,8 +149,8 @@ module BMC::ButtonHelper
150
149
 
151
150
  def import_button(url, **options)
152
151
  options = {
153
- :icon => :upload,
154
- :action => :import,
152
+ icon: :upload,
153
+ action: :import,
155
154
  }.merge(options)
156
155
 
157
156
  bs_button(url, **options)
@@ -159,8 +158,8 @@ module BMC::ButtonHelper
159
158
 
160
159
  def copy_button(url, **options)
161
160
  options = {
162
- :icon => :copy,
163
- :action => :copy,
161
+ icon: :copy,
162
+ action: :copy,
164
163
  }.merge(options)
165
164
 
166
165
  bs_button(url, **options)
@@ -1,15 +1,15 @@
1
1
  module BMC::FiltersHelper
2
2
  def bmc_time_periods_for_select
3
3
  {
4
- t("time_periods.all_time") => "",
5
- t("time_periods.today") => "today",
6
- t("time_periods.yesterday") => "yesterday",
7
- t("time_periods.this_week") => "this_week",
8
- t("time_periods.last_week") => "last_week",
9
- t("time_periods.this_month") => "this_month",
10
- t("time_periods.last_month") => "last_month",
11
- t("time_periods.this_year") => "this_year",
12
- t("time_periods.last_year") => "last_year",
4
+ t("time_periods.all_time") => "",
5
+ t("time_periods.today") => "today",
6
+ t("time_periods.yesterday") => "yesterday",
7
+ t("time_periods.this_week") => "this_week",
8
+ t("time_periods.last_week") => "last_week",
9
+ t("time_periods.this_month") => "this_month",
10
+ t("time_periods.last_month") => "last_month",
11
+ t("time_periods.this_year") => "this_year",
12
+ t("time_periods.last_year") => "last_year",
13
13
  t("time_periods.custom_date") => "custom_date",
14
14
  }
15
15
  end
@@ -8,8 +8,8 @@ module BMC::PaginationHelper
8
8
  end
9
9
 
10
10
  def paginate(objects, options = {})
11
- options = {theme: BMC::PaginationHelper.theme}.merge(options)
12
- super(objects, **options).gsub(/>(\s+)</, "><").html_safe
11
+ options = { theme: BMC::PaginationHelper.theme }.merge(options)
12
+ super(objects, **options).gsub(/>(\s+)</, "><").html_safe # rubocop:disable Rails/OutputSafety
13
13
  end
14
14
 
15
15
  def pagination_infos(collection)
@@ -13,10 +13,10 @@ module BMC::RoutesHelper
13
13
  end
14
14
 
15
15
  opts = {
16
- :controller => "/#{obj.class.to_s.tableize}",
17
- :action => :show,
18
- :id => obj.to_param,
19
- :only_path => true,
16
+ controller: "/#{obj.class.to_s.tableize}",
17
+ action: :show,
18
+ id: obj.to_param,
19
+ only_path: true,
20
20
  }.merge(opts)
21
21
 
22
22
  routes.url_for(opts)
@@ -1,8 +1,6 @@
1
1
  module BMC::SortingHelper
2
2
  def sortable_column(name, column, options = {})
3
- unless column.is_a?(Symbol)
4
- raise ArgumentError, "invalid column, please use symbol"
5
- end
3
+ raise ArgumentError, "invalid column, please use symbol" unless column.is_a?(Symbol)
6
4
 
7
5
  current_column, current_direction = sortable_column_order
8
6
 
@@ -28,7 +26,7 @@ module BMC::SortingHelper
28
26
  end
29
27
  url_params[:sort] = new_sort_param
30
28
 
31
- html_options = {class: klass}.merge(options)
29
+ html_options = { class: klass }.merge(options)
32
30
 
33
31
  link_to(name, url_params, html_options)
34
32
  end
@@ -11,31 +11,31 @@ module BMC::TextHelper
11
11
  end
12
12
  end
13
13
 
14
- def euros(n)
15
- currency(n, "€")
14
+ def euros(value)
15
+ currency(value, "€")
16
16
  end
17
17
 
18
- def currency(n, u)
19
- return if n.nil?
18
+ def currency(value, unit)
19
+ return if value.nil?
20
20
 
21
21
  I18n.t("number.currency.format.format")
22
- .gsub("%n", number(n))
23
- .gsub("%u", u)
22
+ .gsub("%n", number(value))
23
+ .gsub("%u", unit)
24
24
  .tr(" ", nbsp)
25
25
  end
26
26
 
27
- def percentage(n)
28
- return if n.nil?
27
+ def percentage(value)
28
+ return if value.nil?
29
29
 
30
- number(n) + nbsp + "%"
30
+ "#{number(value)}#{nbsp}%"
31
31
  end
32
32
 
33
- def number(n)
34
- return if n.nil?
33
+ def number(value)
34
+ return if value.nil?
35
35
 
36
36
  opts = {}
37
37
 
38
- if n.class.to_s.match?(/Float|Decimal/i)
38
+ if value.class.to_s.match?(/Float|Decimal/i)
39
39
  opts[:precision] = 2
40
40
  else
41
41
  opts[:precision] = 0
@@ -44,11 +44,11 @@ module BMC::TextHelper
44
44
  opts[:delimiter] = I18n.t("number.format.delimiter")
45
45
  opts[:separator] = I18n.t("number.format.separator")
46
46
 
47
- number_with_precision(n, opts).tr(" ", nbsp)
47
+ number_with_precision(value, opts).tr(" ", nbsp)
48
48
  end
49
49
 
50
- def date(d, **args)
51
- I18n.l(d, **args) unless d.nil?
50
+ def date(value, **args)
51
+ I18n.l(value, **args) unless value.nil?
52
52
  end
53
53
 
54
54
  def boolean_icon(bool)
@@ -64,16 +64,16 @@ module BMC::TextHelper
64
64
  return if str.to_s.blank?
65
65
 
66
66
  str = str.delete("\r").strip
67
- strip_tags(str).gsub("\n", "<br />").html_safe
67
+ strip_tags(str).gsub("\n", "<br />").html_safe # rubocop:disable Rails/OutputSafety
68
68
  end
69
69
 
70
70
  def lf2br(str)
71
71
  return if str.to_s.blank?
72
72
 
73
- str.delete("\r").gsub("\n", "<br />").html_safe
73
+ str.delete("\r").gsub("\n", "<br />").html_safe # rubocop:disable Rails/OutputSafety
74
74
  end
75
75
 
76
- def info( # rubocop:disable Metrics/ParameterLists
76
+ def info(
77
77
  object,
78
78
  attribute,
79
79
  value: nil,
@@ -8,7 +8,7 @@ class BMC::CollectionUpdate
8
8
  end
9
9
 
10
10
  def call
11
- return update
11
+ update
12
12
  end
13
13
 
14
14
  def update!
@@ -1,23 +1,9 @@
1
1
  class BMC::MiniModelSerializer::Serializer < BMC::MiniModelSerializer::Serialize
2
- def attributes
3
- raise NotImplementedError
4
- end
2
+ delegate_missing_to :object
3
+
4
+ def attributes = raise NotImplementedError
5
5
 
6
6
  def call
7
7
  serialize(attributes.index_with { |k| send(k) })
8
8
  end
9
-
10
- private
11
-
12
- def method_missing(m, *)
13
- if respond_to_missing?(m)
14
- object.send(m, *)
15
- else
16
- super
17
- end
18
- end
19
-
20
- def respond_to_missing?(m, include_private = false)
21
- super || object.respond_to?(m, true)
22
- end
23
9
  end
@@ -22,14 +22,12 @@ class BMC::TokenGenerator
22
22
  new(*).call
23
23
  end
24
24
 
25
- attr_writer :default_size
25
+ attr_writer :default_size, :default_alphabet
26
26
 
27
27
  def default_size
28
28
  @default_size ||= 64
29
29
  end
30
30
 
31
- attr_writer :default_alphabet
32
-
33
31
  def default_alphabet
34
32
  @default_alphabet ||= (0..9).to_a + ("a".."z").to_a + ("A".."Z").to_a
35
33
  end
@@ -4,9 +4,7 @@ module BMC::ActiveRecordUUIDConcern
4
4
  private
5
5
 
6
6
  def assign_default_uuid
7
- unless self.class.columns_hash["id"].type == :uuid
8
- raise "invalid id type, please change to uuid"
9
- end
7
+ raise "invalid id type, please change to uuid" unless self.class.columns_hash["id"].type == :uuid
10
8
 
11
9
  self.id ||= BMC::SortableUUIDGenerator.call
12
10
  end
@@ -1,8 +1,7 @@
1
1
  module BMC::DefaultValuesConcern
2
2
  extend ActiveSupport::Concern
3
3
 
4
- def assign_default_values
5
- end
4
+ def assign_default_values; end
6
5
 
7
6
  def assign_default(attribute, value)
8
7
  send(:"#{attribute}=", value) if send(attribute).nil?
@@ -11,9 +11,7 @@ module BMC::ModelI18n
11
11
  self.class.t(...)
12
12
  end
13
13
 
14
- def ts
15
- self.class.ts
16
- end
14
+ delegate :ts, to: :class
17
15
 
18
16
  def tv(attribute)
19
17
  value = public_send(attribute)
@@ -25,26 +23,24 @@ module BMC::ModelI18n
25
23
  should_raise = BMC::ModelI18n.raise_on_missing_translations
26
24
  exception_class = BMC::ModelI18n::MissingTranslationError
27
25
 
28
- if should_raise
29
- options = options.merge(default: "")
30
- end
26
+ options = options.merge(default: "") if should_raise
31
27
 
32
28
  if should_raise && attribute.nil?
33
29
  human = model_name.human(options)
34
30
  type = options[:count].to_i > 1 ? "plural" : "singular"
35
31
  raise exception_class, "translation missing: #{self} #{type} model name" if human.blank?
32
+
36
33
  return human
37
34
  end
38
35
 
39
36
  if should_raise && attribute
40
37
  human = human_attribute_name(attribute, options)
41
38
  raise exception_class, "translation missing: #{self}##{attribute}" if human.blank?
39
+
42
40
  return human
43
41
  end
44
42
 
45
- if attribute.nil?
46
- return model_name.human(options)
47
- end
43
+ return model_name.human(options) if attribute.nil?
48
44
 
49
45
  human_attribute_name(attribute, options) if attribute
50
46
  end
@@ -4,21 +4,21 @@ module BMC::Search
4
4
  class_methods do
5
5
  def default_search_fields
6
6
  columns
7
- .select { |column| column.type.in?([:string, :text]) }
7
+ .select { |column| column.type.in?(%i[string text]) }
8
8
  .map { |column| "#{table_name}.#{column.name}" }
9
9
  end # def default_search_fields
10
10
 
11
- def search(q, *fields)
12
- words = q.to_s.parameterize.split("-")
11
+ def search(query, *fields)
12
+ words = query.to_s.parameterize.split("-")
13
13
  fields = default_search_fields if fields.empty?
14
14
 
15
15
  return all if words.empty?
16
16
 
17
- sql_query = words.map.with_index { |_word, index|
18
- fields.map { |field|
17
+ sql_query = words.map.with_index do |_word, index|
18
+ fields.map do |field|
19
19
  "(UNACCENT(CAST(#{field} AS TEXT)) ILIKE :w#{index})"
20
- }.join(" OR ")
21
- }.map { |e| "(#{e})" }.join(" AND ")
20
+ end.join(" OR ")
21
+ end.map { |e| "(#{e})" }.join(" AND ") # rubocop:disable Style/MultilineBlockChain
22
22
 
23
23
  sql_params = words.map.with_index { |word, index| [:"w#{index}", "%#{word}%"] }.to_h
24
24
 
@@ -52,11 +52,12 @@ class BMC::Serializers::Base
52
52
  return :decimal if value.is_a?(Numeric)
53
53
  return :boolean if value.is_a?(TrueClass) || value.is_a?(FalseClass)
54
54
  return :date_or_time if value.is_a?(Date) || value.is_a?(Time)
55
- return :default
55
+
56
+ :default
56
57
  end
57
58
 
58
59
  def format(value)
59
- formatter = "format_" + formatter_for(value).to_s
60
+ formatter = "format_#{formatter_for(value)}"
60
61
  public_send(formatter, value)
61
62
  end
62
63
  end # class << self
@@ -24,13 +24,13 @@ class BMC::Serializers::XLSX < BMC::Serializers::Base
24
24
 
25
25
  def date_range_styles(row)
26
26
  row.each_index.select { row[_1].is_a?(Date) }.map do |col|
27
- {range: {rows: :all, columns: col}, styles: {format_code: "dd/mm/yyyy"}}
27
+ { range: { rows: :all, columns: col }, styles: { format_code: "dd/mm/yyyy" } }
28
28
  end
29
29
  end
30
30
 
31
31
  def time_range_styles(row)
32
32
  row.each_index.select { row[_1].is_a?(Time) }.map do |col|
33
- {range: {rows: :all, columns: col}, styles: {format_code: "dd/mm/yyyy hh:mm:ss"}}
33
+ { range: { rows: :all, columns: col }, styles: { format_code: "dd/mm/yyyy hh:mm:ss" } }
34
34
  end
35
35
  end
36
36
  end
@@ -27,16 +27,16 @@ class BMC::SMS::ApplicationSMS
27
27
  class << self
28
28
  private :new
29
29
 
30
- def method_missing(m, ...)
31
- if respond_to_missing?(m)
32
- new(action_name: m).public_send(m, ...)
30
+ def method_missing(method, ...)
31
+ if respond_to_missing?(method)
32
+ new(action_name: method).public_send(method, ...)
33
33
  else
34
34
  super
35
35
  end
36
36
  end
37
37
 
38
- def respond_to_missing?(m, include_private = false)
39
- super || public_instance_methods.include?(m)
38
+ def respond_to_missing?(method, include_private = false)
39
+ super || public_instance_methods.include?(method)
40
40
  end
41
41
  end # class << self
42
42
  end
@@ -2,16 +2,16 @@ class BMC::SMS::Strategies::Amazon
2
2
  attr_reader :region, :access_key_id, :secret_access_key
3
3
 
4
4
  def initialize(region: nil, access_key_id: nil, secret_access_key: nil)
5
- @region = region || ENV["SNS_REGION"] || ENV["AWS_REGION"]
6
- @access_key_id = access_key_id || ENV["SNS_ACCESS_KEY_ID"] || ENV["AWS_ACCESS_KEY_ID"]
7
- @secret_access_key = secret_access_key || ENV["SNS_SECRET_ACCESS_KEY"] || ENV["AWS_SECRET_ACCESS_KEY"]
5
+ @region = region || ENV["SNS_REGION"] || ENV.fetch("AWS_REGION", nil)
6
+ @access_key_id = access_key_id || ENV["SNS_ACCESS_KEY_ID"] || ENV.fetch("AWS_ACCESS_KEY_ID", nil)
7
+ @secret_access_key = secret_access_key || ENV["SNS_SECRET_ACCESS_KEY"] || ENV.fetch("AWS_SECRET_ACCESS_KEY", nil)
8
8
  end
9
9
 
10
10
  def client
11
11
  @client ||= Aws::SNS::Client.new(
12
- :region => region,
13
- :access_key_id => access_key_id,
14
- :secret_access_key => secret_access_key,
12
+ region: region,
13
+ access_key_id: access_key_id,
14
+ secret_access_key: secret_access_key,
15
15
  )
16
16
  end
17
17
 
@@ -19,16 +19,16 @@ class BMC::SMS::Strategies::Amazon
19
19
  from = data[:from] || BMC::SMS.default_from
20
20
 
21
21
  client.publish(
22
- :phone_number => data[:to],
23
- :message => data[:body],
24
- :message_attributes => {
22
+ phone_number: data[:to],
23
+ message: data[:body],
24
+ message_attributes: {
25
25
  "AWS.SNS.SMS.SenderID" => {
26
- :data_type => "String",
27
- :string_value => from,
26
+ data_type: "String",
27
+ string_value: from,
28
28
  },
29
29
  "AWS.SNS.SMS.SMSType" => {
30
- :data_type => "String",
31
- :string_value => "Transactional",
30
+ data_type: "String",
31
+ string_value: "Transactional",
32
32
  },
33
33
  },
34
34
  )
@@ -1,11 +1,11 @@
1
1
  class BMC::SMS::Strategies::Sendinblue
2
- URL = "https://api.sendinblue.com/v3/transactionalSMS/sms"
2
+ URL = "https://api.sendinblue.com/v3/transactionalSMS/sms".freeze
3
3
 
4
4
  DeliveryError = Class.new(BMC::SMS::DeliveryError)
5
5
 
6
6
  attr_reader :api_key
7
7
 
8
- def initialize(api_key: ENV["SENDINBLUE_API_KEY"])
8
+ def initialize(api_key: ENV.fetch("SENDINBLUE_API_KEY", nil))
9
9
  @api_key = api_key
10
10
  end
11
11
 
@@ -23,8 +23,8 @@ class BMC::SMS::Strategies::Sendinblue
23
23
 
24
24
  def request_headers
25
25
  {
26
- :content_type => "application/json",
27
- :api_key => api_key,
26
+ content_type: "application/json",
27
+ api_key: api_key,
28
28
  }
29
29
  end
30
30
 
@@ -32,10 +32,10 @@ class BMC::SMS::Strategies::Sendinblue
32
32
  from = data[:from] || BMC::SMS.default_from
33
33
 
34
34
  {
35
- :type => "transactional",
36
- :sender => from,
37
- :recipient => data[:to],
38
- :content => data[:body],
35
+ type: "transactional",
36
+ sender: from,
37
+ recipient: data[:to],
38
+ content: data[:body],
39
39
  }
40
40
  end
41
41
  end
@@ -28,7 +28,7 @@ class BMC::Sorter
28
28
  private
29
29
 
30
30
  def inverted_direction
31
- {asc: :desc, desc: :asc}[direction]
31
+ { asc: :desc, desc: :asc }[direction]
32
32
  end
33
33
 
34
34
  def joins(...)
@@ -39,11 +39,11 @@ class BMC::Sorter
39
39
  @collection = @collection.left_joins(...)
40
40
  end
41
41
 
42
- def by_column(c = column)
43
- {c => direction}
42
+ def by_column(column = self.column)
43
+ { column => direction }
44
44
  end
45
45
 
46
- def by_lower(c = column)
47
- Arel.sql "LOWER(#{c}) #{direction}"
46
+ def by_lower(column = self.column)
47
+ Arel.sql "LOWER(#{column}) #{direction}"
48
48
  end
49
49
  end
@@ -3,6 +3,7 @@ module BMC::ActiveModelCustomErrorMessages
3
3
  module ForErrors
4
4
  def full_message(attribute, message)
5
5
  return message[1..] if message[0] == "^"
6
+
6
7
  super
7
8
  end
8
9
  end
@@ -13,6 +14,7 @@ module BMC::ActiveModelCustomErrorMessages
13
14
  module ForError
14
15
  def full_message
15
16
  return message[1..] if message[0] == "^"
17
+
16
18
  super
17
19
  end
18
20
  end
@@ -4,7 +4,7 @@ module BMC::ActiveModelTypeCast
4
4
  if value.is_a?(String)
5
5
  super(value.tr(",", ".").gsub(/[^-0-9.]/, ""))
6
6
  else
7
- super(value)
7
+ super
8
8
  end
9
9
  end
10
10
  end
@@ -14,14 +14,14 @@ module BMC::ActiveModelTypeCast
14
14
  SANITIZABLE_FORMATS = [
15
15
  /^[0-9]{2}\/[0-9]{2}\/[0-9]{4}$/,
16
16
  /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/,
17
- ]
17
+ ].freeze
18
18
  # rubocop:enable Style/RegexpLiteral
19
19
 
20
20
  def cast_value(value)
21
21
  if sanitizable?(value)
22
22
  super(sanitize(value))
23
23
  else
24
- super(value)
24
+ super
25
25
  end
26
26
  end
27
27
 
@@ -33,6 +33,7 @@ module BMC::ActiveModelTypeCast
33
33
 
34
34
  def sanitizable?(value)
35
35
  return false unless value.is_a?(String)
36
+
36
37
  sanitized = sanitize(value)
37
38
  SANITIZABLE_FORMATS.any? { |r| r =~ sanitized }
38
39
  end
@@ -41,7 +42,7 @@ module BMC::ActiveModelTypeCast
41
42
  module Boolean
42
43
  def cast_value(value)
43
44
  value = value.strip if value.is_a?(String)
44
- super(value)
45
+ super
45
46
  end
46
47
  end
47
48
  end
data/lib/bmc/config.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  class << BMC
2
- attr_writer :parent_controller
2
+ attr_writer :parent_controller, :parent_job, :parent_mailer
3
3
 
4
4
  def parent_controller
5
5
  @parent_controller ||= [
@@ -8,8 +8,6 @@ class << BMC
8
8
  ].filter_map(&:safe_constantize).first
9
9
  end
10
10
 
11
- attr_writer :parent_job
12
-
13
11
  def parent_job
14
12
  @parent_job ||= [
15
13
  "ApplicationJob",
@@ -17,8 +15,6 @@ class << BMC
17
15
  ].filter_map(&:safe_constantize).first
18
16
  end
19
17
 
20
- attr_writer :parent_mailer
21
-
22
18
  def parent_mailer
23
19
  @parent_mailer ||= [
24
20
  "ApplicationMailer",
data/lib/bmc/engine.rb CHANGED
@@ -1,8 +1,5 @@
1
- require "awesome_print"
2
- require "pry-rails"
3
1
  require "rails-i18n"
4
2
  require "nilify_blanks"
5
- require "tapenade"
6
3
  require "attr_extras/explicit"
7
4
 
8
5
  module BMC
@@ -3,7 +3,7 @@ class BMC::ErrorsMiddleware
3
3
  "ActiveRecord::ConnectionTimeoutError",
4
4
  "connections on port 5432",
5
5
  "PG::UnableToSend",
6
- ]
6
+ ].freeze
7
7
 
8
8
  NOT_ACCEPTABLE_ERRORS = [
9
9
  "ActionController::BadRequest",
@@ -13,7 +13,7 @@ class BMC::ErrorsMiddleware
13
13
  "ActionDispatch::Http::MimeNegotiation::InvalidType",
14
14
  "ActionView::MissingTemplate",
15
15
  "Mime::Type::InvalidMimeType",
16
- ]
16
+ ].freeze
17
17
 
18
18
  def initialize(app)
19
19
  @app = app
@@ -24,13 +24,9 @@ class BMC::ErrorsMiddleware
24
24
  rescue StandardError => e
25
25
  error = "#{e.class} : #{e.message}"
26
26
 
27
- if MAINTENANCE_ERRORS.any? { |pattern| error.match?(pattern) }
28
- return respond_with 503, "Maintenance en cours."
29
- end
27
+ return respond_with 503, "Maintenance en cours." if MAINTENANCE_ERRORS.any? { |pattern| error.match?(pattern) }
30
28
 
31
- if NOT_ACCEPTABLE_ERRORS.any? { |pattern| error.match?(pattern) }
32
- return respond_with 406, "Not acceptable."
33
- end
29
+ return respond_with 406, "Not acceptable." if NOT_ACCEPTABLE_ERRORS.any? { |pattern| error.match?(pattern) }
34
30
 
35
31
  raise e
36
32
  end
@@ -38,7 +34,7 @@ class BMC::ErrorsMiddleware
38
34
  private
39
35
 
40
36
  def respond_with(status, body)
41
- [status, {"Content-Type" => "text/plain; charset=UTF-8"}, [body]]
37
+ [status, { "Content-Type" => "text/plain; charset=UTF-8" }, [body]]
42
38
  end
43
39
  end
44
40
 
@@ -1,17 +1,17 @@
1
1
  module BMC::FormBackUrl
2
2
  def back_url_tag
3
3
  tag.input(
4
- :type => "hidden",
5
- :name => "back_url",
6
- :value => params[:back_url].presence || request.referer,
4
+ type: "hidden",
5
+ name: "back_url",
6
+ value: params[:back_url].presence || request.referer,
7
7
  )
8
8
  end
9
9
 
10
10
  def form_tag_with_body(html_options, content)
11
11
  output = form_tag_html(html_options)
12
- output.safe_concat(back_url_tag)
12
+ output.safe_concat(back_url_tag) # rubocop:disable Rails/OutputSafety
13
13
  output << content
14
- output.safe_concat("</form>")
14
+ output.safe_concat("</form>") # rubocop:disable Rails/OutputSafety
15
15
  end
16
16
  end
17
17
 
data/lib/bmc/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module BMC
2
- VERSION = "1.6.2"
2
+ VERSION = "1.8.0".freeze
3
3
  end
metadata CHANGED
@@ -1,31 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bmc
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.2
4
+ version: 1.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Benoit MARTIN-CHAVE
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2025-02-12 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
- name: rails-i18n
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '0'
27
- - !ruby/object:Gem::Dependency
28
- name: awesome_print
13
+ name: addressable
29
14
  requirement: !ruby/object:Gem::Requirement
30
15
  requirements:
31
16
  - - ">="
@@ -39,7 +24,7 @@ dependencies:
39
24
  - !ruby/object:Gem::Version
40
25
  version: '0'
41
26
  - !ruby/object:Gem::Dependency
42
- name: pry-rails
27
+ name: attr_extras
43
28
  requirement: !ruby/object:Gem::Requirement
44
29
  requirements:
45
30
  - - ">="
@@ -67,35 +52,7 @@ dependencies:
67
52
  - !ruby/object:Gem::Version
68
53
  version: '0'
69
54
  - !ruby/object:Gem::Dependency
70
- name: tapenade
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :runtime
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: addressable
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :runtime
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: attr_extras
55
+ name: rails-i18n
99
56
  requirement: !ruby/object:Gem::Requirement
100
57
  requirements:
101
58
  - - ">="
@@ -152,7 +109,6 @@ files:
152
109
  - app/libs/bmc/collection_update.rb
153
110
  - app/libs/bmc/mini_model_serializer/serialize.rb
154
111
  - app/libs/bmc/mini_model_serializer/serializer.rb
155
- - app/libs/bmc/monkey.rb
156
112
  - app/libs/bmc/sortable_uuid_generator.rb
157
113
  - app/libs/bmc/token_generator.rb
158
114
  - app/mailers/bmc/application_mailer.rb
@@ -163,7 +119,6 @@ files:
163
119
  - app/models/concerns/bmc/model_to_s.rb
164
120
  - app/models/concerns/bmc/pluck_distinct.rb
165
121
  - app/models/concerns/bmc/pluck_to_hash.rb
166
- - app/models/concerns/bmc/polymorphic_id.rb
167
122
  - app/models/concerns/bmc/search.rb
168
123
  - app/models/concerns/bmc/timestamp_helpers.rb
169
124
  - app/serializers/bmc/serializers.rb
@@ -214,8 +169,8 @@ files:
214
169
  homepage: https://gitlab.benoitmc.com/pub/bmc
215
170
  licenses:
216
171
  - MIT
217
- metadata: {}
218
- post_install_message:
172
+ metadata:
173
+ rubygems_mfa_required: 'true'
219
174
  rdoc_options: []
220
175
  require_paths:
221
176
  - lib
@@ -223,15 +178,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
223
178
  requirements:
224
179
  - - ">="
225
180
  - !ruby/object:Gem::Version
226
- version: 2.7.2
181
+ version: 3.3.0
227
182
  required_rubygems_version: !ruby/object:Gem::Requirement
228
183
  requirements:
229
184
  - - ">="
230
185
  - !ruby/object:Gem::Version
231
186
  version: '0'
232
187
  requirements: []
233
- rubygems_version: 3.5.22
234
- signing_key:
188
+ rubygems_version: 3.6.9
235
189
  specification_version: 4
236
190
  summary: BMC
237
191
  test_files: []
@@ -1,39 +0,0 @@
1
- module BMC::Monkey
2
- extend ActiveSupport::Concern
3
-
4
- class_methods do
5
- def prepend_instances(&block)
6
- m = Module.new(&block)
7
- send(:prepend, m)
8
- end
9
-
10
- def prepend_class(&block)
11
- m = Module.new(&block)
12
- singleton_class.send(:prepend, m)
13
- end
14
-
15
- def prepend_instance_method(name, &block)
16
- check_instance_method_exist!(name)
17
-
18
- m = Module.new
19
- m.send(:define_method, name, &block)
20
- send(:prepend, m)
21
- end
22
-
23
- def prepend_class_method(name, &block)
24
- check_class_method_exist!(name)
25
-
26
- m = Module.new
27
- m.send(:define_method, name, &block)
28
- singleton_class.send(:prepend, m)
29
- end
30
-
31
- def check_instance_method_exist!(name)
32
- raise "instance method `#{name}` does not exist" unless instance_methods.include?(name)
33
- end
34
-
35
- def check_class_method_exist!(name)
36
- raise "class method `#{name}` does not exist" unless methods.include?(name)
37
- end
38
- end
39
- end
@@ -1,37 +0,0 @@
1
- module BMC::PolymorphicId
2
- extend ActiveSupport::Concern
3
-
4
- included do
5
- def self.polymorphic_id_for(relation_name)
6
- module_src = File.read(__FILE__).split("__END__").last
7
- module_src = module_src.gsub("relation", relation_name.to_s)
8
- send :include, eval(module_src)
9
- end
10
-
11
- def guid
12
- return nil if new_record?
13
-
14
- "#{self.class.base_class}-#{id}"
15
- end
16
- end # included
17
- end # module
18
-
19
- __END__
20
-
21
- Module.new do
22
- def relation_guid
23
- return nil if relation_type.blank? || relation_id.blank?
24
-
25
- "#{relation_type}-#{relation_id}"
26
- end
27
-
28
- def relation_guid=(guid)
29
- if guid.blank?
30
- self.relation = nil
31
- return
32
- end
33
-
34
- type, id = guid.split("-", 2)
35
- self.relation = type.constantize.find(id)
36
- end
37
- end