bmc 1.6.2 → 1.7.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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -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/errors_middleware.rb +5 -9
  36. data/lib/bmc/form_back_url.rb +5 -5
  37. data/lib/bmc/version.rb +1 -1
  38. metadata +12 -16
  39. data/app/libs/bmc/monkey.rb +0 -39
  40. 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: df08b33875ae05d3bd5725a47921f9156a540ddcca15f8f7727ad64ad09f0f52
4
+ data.tar.gz: d4650f71805c25b89ab80655ed12164df5081216fa1ca79f4a655c3d830939f5
5
5
  SHA512:
6
- metadata.gz: 37f284b2e4103367199856fb20017b509eb7834f0e57e73721a05dede3750df48d3e843fcbd1b3870f3fc1280eb169425bac011c9ef5c70708d004abaa3f5265
7
- data.tar.gz: f5f269c338dfc62ae11e9c7db9b42e5d6afa8e475ea10e707cac85f428a3cb6ac7def5018e4914b2c147b88d1f91aafe47aae8de95dc074a03bc1a92587873fa
6
+ metadata.gz: '019f2873b3a0e4157a6ca143f54090b676fa056ccc4128a4ab5152e460967c3e82fefbf235c6f0016c6cbee550c4b27bd8a9b385f4232a1f4ac45f59df1000b4'
7
+ data.tar.gz: 81fccca06be5ebb574b625ac2484500f3e838339ce5cd31e18c1012f7d2688b199a59dcff76031ee837734b82808f53033209aa6aaf2f859882db04957939b60
data/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  ## Next version
4
4
 
5
+ ## v1.7.0
6
+ - Rails 8.0
7
+ - Ruby 3.3.0 minimum
8
+ - Fix to `Filter#actives_count` to handle `[""]` value
9
+ - Fix Rubocop
10
+
5
11
  ## v1.6.2
6
12
  - `ApiControllerConcern` change
7
13
 
@@ -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",
@@ -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.7.0".freeze
3
3
  end
metadata CHANGED
@@ -1,17 +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.7.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
13
+ name: addressable
15
14
  requirement: !ruby/object:Gem::Requirement
16
15
  requirements:
17
16
  - - ">="
@@ -25,7 +24,7 @@ dependencies:
25
24
  - !ruby/object:Gem::Version
26
25
  version: '0'
27
26
  - !ruby/object:Gem::Dependency
28
- name: awesome_print
27
+ name: attr_extras
29
28
  requirement: !ruby/object:Gem::Requirement
30
29
  requirements:
31
30
  - - ">="
@@ -39,7 +38,7 @@ dependencies:
39
38
  - !ruby/object:Gem::Version
40
39
  version: '0'
41
40
  - !ruby/object:Gem::Dependency
42
- name: pry-rails
41
+ name: awesome_print
43
42
  requirement: !ruby/object:Gem::Requirement
44
43
  requirements:
45
44
  - - ">="
@@ -67,7 +66,7 @@ dependencies:
67
66
  - !ruby/object:Gem::Version
68
67
  version: '0'
69
68
  - !ruby/object:Gem::Dependency
70
- name: tapenade
69
+ name: pry-rails
71
70
  requirement: !ruby/object:Gem::Requirement
72
71
  requirements:
73
72
  - - ">="
@@ -81,7 +80,7 @@ dependencies:
81
80
  - !ruby/object:Gem::Version
82
81
  version: '0'
83
82
  - !ruby/object:Gem::Dependency
84
- name: addressable
83
+ name: rails-i18n
85
84
  requirement: !ruby/object:Gem::Requirement
86
85
  requirements:
87
86
  - - ">="
@@ -95,7 +94,7 @@ dependencies:
95
94
  - !ruby/object:Gem::Version
96
95
  version: '0'
97
96
  - !ruby/object:Gem::Dependency
98
- name: attr_extras
97
+ name: tapenade
99
98
  requirement: !ruby/object:Gem::Requirement
100
99
  requirements:
101
100
  - - ">="
@@ -152,7 +151,6 @@ files:
152
151
  - app/libs/bmc/collection_update.rb
153
152
  - app/libs/bmc/mini_model_serializer/serialize.rb
154
153
  - app/libs/bmc/mini_model_serializer/serializer.rb
155
- - app/libs/bmc/monkey.rb
156
154
  - app/libs/bmc/sortable_uuid_generator.rb
157
155
  - app/libs/bmc/token_generator.rb
158
156
  - app/mailers/bmc/application_mailer.rb
@@ -163,7 +161,6 @@ files:
163
161
  - app/models/concerns/bmc/model_to_s.rb
164
162
  - app/models/concerns/bmc/pluck_distinct.rb
165
163
  - app/models/concerns/bmc/pluck_to_hash.rb
166
- - app/models/concerns/bmc/polymorphic_id.rb
167
164
  - app/models/concerns/bmc/search.rb
168
165
  - app/models/concerns/bmc/timestamp_helpers.rb
169
166
  - app/serializers/bmc/serializers.rb
@@ -214,8 +211,8 @@ files:
214
211
  homepage: https://gitlab.benoitmc.com/pub/bmc
215
212
  licenses:
216
213
  - MIT
217
- metadata: {}
218
- post_install_message:
214
+ metadata:
215
+ rubygems_mfa_required: 'true'
219
216
  rdoc_options: []
220
217
  require_paths:
221
218
  - lib
@@ -223,15 +220,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
223
220
  requirements:
224
221
  - - ">="
225
222
  - !ruby/object:Gem::Version
226
- version: 2.7.2
223
+ version: 3.3.0
227
224
  required_rubygems_version: !ruby/object:Gem::Requirement
228
225
  requirements:
229
226
  - - ">="
230
227
  - !ruby/object:Gem::Version
231
228
  version: '0'
232
229
  requirements: []
233
- rubygems_version: 3.5.22
234
- signing_key:
230
+ rubygems_version: 3.6.9
235
231
  specification_version: 4
236
232
  summary: BMC
237
233
  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