dorsale 3.4.0 → 3.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -2
- data/app/assets/javascripts/dorsale/common/upload.coffee +25 -0
- data/app/assets/javascripts/dorsale/dependencies.coffee +1 -0
- data/app/assets/stylesheets/dorsale/all.sass +0 -1
- data/app/assets/stylesheets/dorsale/common.sass +0 -4
- data/app/assets/stylesheets/dorsale/dependencies.sass +2 -1
- data/app/controllers/dorsale/application_controller.rb +2 -2
- data/app/controllers/dorsale/flyboy/tasks_controller.rb +3 -3
- data/app/filters/dorsale/billing_machine/small_data/filter_for_invoices.rb +5 -5
- data/app/filters/dorsale/billing_machine/small_data/filter_for_quotations.rb +5 -5
- data/app/filters/dorsale/billing_machine/small_data/filter_strategy_by_customer.rb +1 -1
- data/app/filters/dorsale/billing_machine/small_data/filter_strategy_by_payment_status.rb +1 -1
- data/app/filters/dorsale/billing_machine/small_data/filter_strategy_by_state.rb +1 -1
- data/app/filters/dorsale/customer_vault/small_data/filter_for_people.rb +3 -3
- data/app/filters/dorsale/expense_gun/small_data/filter_for_expenses.rb +3 -3
- data/app/filters/dorsale/flyboy/small_data/filter_for_tasks.rb +2 -2
- data/app/filters/dorsale/flyboy/small_data/filter_strategy_by_done.rb +1 -1
- data/app/helpers/dorsale/all_helpers.rb +2 -10
- data/app/helpers/dorsale/flyboy/application_helper.rb +2 -2
- data/app/models/dorsale/application_record.rb +7 -9
- data/app/models/dorsale/customer_vault/person.rb +1 -1
- data/app/models/dorsale/flyboy/task.rb +1 -1
- data/app/views/dorsale/billing_machine/invoices/_filters.html.slim +2 -2
- data/app/views/dorsale/billing_machine/invoices/_show_actions.html.slim +2 -2
- data/app/views/dorsale/billing_machine/invoices/index.xlsx.ruby +1 -1
- data/app/views/dorsale/billing_machine/quotations/_filters.html.slim +2 -2
- data/app/views/dorsale/billing_machine/quotations/_show_actions.html.slim +1 -1
- data/app/views/dorsale/customer_vault/people/index.xlsx.ruby +1 -1
- data/app/views/dorsale/expense_gun/expenses/_show_actions.html.slim +4 -4
- data/app/views/dorsale/flyboy/tasks/index.xlsx.ruby +1 -1
- data/config/locales/dorsale.en.yml +11 -1
- data/config/locales/dorsale.fr.yml +10 -0
- data/config/routes.rb +0 -6
- data/lib/dorsale/engine.rb +4 -1
- data/lib/dorsale/version.rb +1 -1
- metadata +17 -69
- data/app/assets/javascripts/dorsale/common/forms.coffee +0 -58
- data/app/assets/javascripts/dorsale/common/modals.coffee +0 -126
- data/app/assets/stylesheets/dorsale/common/filters.sass +0 -43
- data/app/assets/stylesheets/dorsale/common/flash.sass +0 -6
- data/app/assets/stylesheets/dorsale/common/modals.sass +0 -45
- data/app/assets/stylesheets/dorsale/common/pagination.sass +0 -8
- data/app/assets/stylesheets/dorsale/print.sass +0 -74
- data/app/controllers/concerns/dorsale/back_url_concern.rb +0 -18
- data/app/controllers/dorsale/small_data/filters_controller.rb +0 -36
- data/app/filters/dorsale/small_data/filter.rb +0 -68
- data/app/filters/dorsale/small_data/filter_strategy.rb +0 -5
- data/app/filters/dorsale/small_data/filter_strategy_by_date.rb +0 -6
- data/app/filters/dorsale/small_data/filter_strategy_by_date_begin.rb +0 -6
- data/app/filters/dorsale/small_data/filter_strategy_by_date_end.rb +0 -6
- data/app/filters/dorsale/small_data/filter_strategy_by_key_value.rb +0 -16
- data/app/filters/dorsale/small_data/filter_strategy_by_tags.rb +0 -11
- data/app/filters/dorsale/small_data/filter_strategy_by_time_period.rb +0 -37
- data/app/helpers/dorsale/bootstrap_helper.rb +0 -6
- data/app/helpers/dorsale/button_helper.rb +0 -161
- data/app/helpers/dorsale/filters_helper.rb +0 -68
- data/app/helpers/dorsale/form_helper.rb +0 -49
- data/app/helpers/dorsale/link_helper.rb +0 -52
- data/app/helpers/dorsale/pagination_helper.rb +0 -6
- data/app/helpers/dorsale/routes_helper.rb +0 -20
- data/app/helpers/dorsale/sorting_helper.rb +0 -48
- data/app/helpers/dorsale/text_helper.rb +0 -121
- data/app/libs/dorsale/sortable_uuid_generator.rb +0 -11
- data/app/models/concerns/dorsale/active_record_uuid_concern.rb +0 -15
- data/app/models/concerns/dorsale/default_values_concern.rb +0 -13
- data/app/models/concerns/dorsale/model_i18n.rb +0 -25
- data/app/models/concerns/dorsale/model_to_s.rb +0 -9
- data/app/models/concerns/dorsale/polymorphic_id.rb +0 -34
- data/app/models/concerns/dorsale/search.rb +0 -30
- data/app/models/dorsale/small_data.rb +0 -2
- data/app/serializers/dorsale/serializers.rb +0 -2
- data/app/serializers/dorsale/serializers/base.rb +0 -17
- data/app/serializers/dorsale/serializers/xlsx.rb +0 -36
- data/app/views/dorsale/search/_form.html.slim +0 -6
- data/config/locales/common.en.yml +0 -210
- data/config/locales/common.fr.yml +0 -220
- data/lib/dorsale/active_record_comma_type_cast.rb +0 -12
- data/lib/dorsale/core_and_rails_ext.rb +0 -3
- data/lib/dorsale/form_back_url.rb +0 -18
- data/spec/controllers/dorsale/small_data/filters_controller_spec.rb +0 -60
- data/spec/filters/dorsale/small_data/filter_spec.rb +0 -39
- data/spec/helpers/dorsale/form_helper_spec.rb +0 -11
- data/spec/helpers/dorsale/link_helper_spec.rb +0 -31
- data/spec/helpers/dorsale/sorting_helper_spec.rb +0 -74
- data/spec/helpers/dorsale/text_helper_spec.rb +0 -123
- data/spec/libs/dorsale/active_record_comma_type_cast_spec.rb +0 -44
- data/spec/libs/dorsale/polymorphic_id_spec.rb +0 -30
- data/spec/libs/dorsale/sortable_uuid_generator_spec.rb +0 -29
- data/spec/models/concerns/dorsale/model_i18n_spec.rb +0 -21
- data/spec/routing/dorsale/small_data_routing_spec.rb +0 -15
- data/spec/serializers/dorsale/serializers/xlsx_spec.rb +0 -33
@@ -1,68 +0,0 @@
|
|
1
|
-
module Dorsale::FiltersHelper
|
2
|
-
def filter_submit_button(options = {})
|
3
|
-
options[:class] ||= "btn submit filter-submit"
|
4
|
-
options[:type] ||= "submit"
|
5
|
-
options[:value] ||= "submit"
|
6
|
-
|
7
|
-
text = options.delete(:text) || t("actions.filter")
|
8
|
-
icon = options.delete(:icon) || "filter"
|
9
|
-
|
10
|
-
content_tag(:button, options) do
|
11
|
-
icon(icon) + " " + text
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
def filter_reset_button(options = {})
|
16
|
-
options[:class] ||= "btn reset filter-reset"
|
17
|
-
options[:type] ||= "submit"
|
18
|
-
options[:value] ||= "reset"
|
19
|
-
|
20
|
-
text = options.delete(:text) || t("actions.reset")
|
21
|
-
icon = options.delete(:icon) || "rotate-left"
|
22
|
-
|
23
|
-
content_tag(:button, options) do
|
24
|
-
icon(icon) + " " + text
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def filter_buttons
|
29
|
-
filter_reset_button + filter_submit_button
|
30
|
-
end
|
31
|
-
|
32
|
-
def filters_form(options = {}, &block)
|
33
|
-
if options.key?(:buttons)
|
34
|
-
buttons = optins.delete(:buttons)
|
35
|
-
else
|
36
|
-
buttons = true
|
37
|
-
end
|
38
|
-
|
39
|
-
options = {
|
40
|
-
:url => dorsale.small_data_filters_path,
|
41
|
-
:wrapper => :inline_form,
|
42
|
-
}.merge(options)
|
43
|
-
|
44
|
-
html = simple_form_for(:filters, options, &block)
|
45
|
-
|
46
|
-
if buttons
|
47
|
-
html = html.gsub("</form>", "#{filter_buttons}</form>").html_safe
|
48
|
-
end
|
49
|
-
|
50
|
-
html
|
51
|
-
end
|
52
|
-
|
53
|
-
def dorsale_time_periods_for_select
|
54
|
-
{
|
55
|
-
t("time_periods.all_time") => "",
|
56
|
-
t("time_periods.today") => "today",
|
57
|
-
t("time_periods.yesterday") => "yesterday" ,
|
58
|
-
t("time_periods.this_week") => "this_week",
|
59
|
-
t("time_periods.last_week") => "last_week",
|
60
|
-
t("time_periods.this_month") => "this_month",
|
61
|
-
t("time_periods.last_month") => "last_month",
|
62
|
-
t("time_periods.this_year") => "this_year",
|
63
|
-
t("time_periods.last_year") => "last_year",
|
64
|
-
t("time_periods.custom_date") => "custom_date",
|
65
|
-
}
|
66
|
-
end
|
67
|
-
|
68
|
-
end
|
@@ -1,49 +0,0 @@
|
|
1
|
-
module Dorsale::FormHelper
|
2
|
-
def form_buttons(opts = {})
|
3
|
-
back_url = opts[:back_url]
|
4
|
-
back_url = url_for(:back).html_safe if back_url.blank?
|
5
|
-
back_url = URI(back_url).path if back_url.include?("://")
|
6
|
-
|
7
|
-
if opts[:obj].present?
|
8
|
-
if opts[:obj].new_record?
|
9
|
-
submit_action = :create
|
10
|
-
else
|
11
|
-
submit_action = :update
|
12
|
-
end
|
13
|
-
else
|
14
|
-
submit_action = :save
|
15
|
-
end
|
16
|
-
|
17
|
-
content_tag("div", class: "actions") do
|
18
|
-
submit = content_tag(:button, type: :submit, class: "btn btn-sm btn-success") do
|
19
|
-
content_tag(:span, class: "fa fa-save") {} + " " + t("actions.#{submit_action}")
|
20
|
-
end
|
21
|
-
|
22
|
-
cancel = content_tag("a", href: back_url, class: "btn btn-primary btn-sm") do
|
23
|
-
content_tag(:span, class: "fa fa-times"){} + " " + t("actions.cancel")
|
24
|
-
end
|
25
|
-
|
26
|
-
cancel = "" if back_url == false
|
27
|
-
|
28
|
-
submit + cancel
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def horizontal_form_for(obj, opts={}, &block)
|
33
|
-
opts = {
|
34
|
-
:wrapper => "horizontal_form",
|
35
|
-
:html => {
|
36
|
-
:class => "form-horizontal"
|
37
|
-
}
|
38
|
-
}.deep_merge(opts)
|
39
|
-
|
40
|
-
simple_form_for(obj, opts, &block)
|
41
|
-
end
|
42
|
-
|
43
|
-
def search_form(opts = {})
|
44
|
-
action = opts.delete(:action) || request.fullpath
|
45
|
-
|
46
|
-
render "dorsale/search/form", action: action
|
47
|
-
end
|
48
|
-
|
49
|
-
end
|
@@ -1,52 +0,0 @@
|
|
1
|
-
module Dorsale::LinkHelper
|
2
|
-
def link_to_object(obj, options = {})
|
3
|
-
return if obj.nil?
|
4
|
-
|
5
|
-
if policy(obj).read?
|
6
|
-
link_to(obj.to_s, engine_polymorphic_path(obj), options)
|
7
|
-
else
|
8
|
-
obj.to_s
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
def icon_link_to(icon, name, options = nil, html_options = nil, &block)
|
13
|
-
name = "#{icon(icon)} #{name}".html_safe
|
14
|
-
link_to(name, options, html_options, &block)
|
15
|
-
end
|
16
|
-
|
17
|
-
def web_link(text, opts = {})
|
18
|
-
return if text.to_s.blank?
|
19
|
-
|
20
|
-
href = text
|
21
|
-
href = "http://#{text}" unless text.include?("://")
|
22
|
-
|
23
|
-
link_to(text, href, opts)
|
24
|
-
end
|
25
|
-
|
26
|
-
def email_link(text, opts = {})
|
27
|
-
return if text.to_s.blank?
|
28
|
-
|
29
|
-
href = "mailto:#{text}"
|
30
|
-
|
31
|
-
link_to(text, href, opts)
|
32
|
-
end
|
33
|
-
|
34
|
-
def tel_link(text, opts = {})
|
35
|
-
return if text.to_s.blank?
|
36
|
-
|
37
|
-
value = text.gsub(" ", "")
|
38
|
-
href = "tel:#{value}"
|
39
|
-
|
40
|
-
link_to(text, href, opts)
|
41
|
-
end
|
42
|
-
|
43
|
-
def twitter_link(text, opts = {})
|
44
|
-
return if text.to_s.blank?
|
45
|
-
|
46
|
-
href = text
|
47
|
-
href = "https://twitter.com/#{text}" unless text.include?("twitter.com")
|
48
|
-
href = "https://#{text}" unless href.include?("://")
|
49
|
-
|
50
|
-
link_to(text, href, opts)
|
51
|
-
end
|
52
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
module Dorsale::RoutesHelper
|
2
|
-
def engine_polymorphic_path(obj, opts = {})
|
3
|
-
engine = obj.class.parents[-2]
|
4
|
-
|
5
|
-
if engine.nil?
|
6
|
-
routes = main_app
|
7
|
-
else
|
8
|
-
routes = engine::Engine.routes
|
9
|
-
end
|
10
|
-
|
11
|
-
opts = {
|
12
|
-
:controller => "/#{obj.class.to_s.tableize}",
|
13
|
-
:action => :show,
|
14
|
-
:id => obj.to_param,
|
15
|
-
:only_path => true
|
16
|
-
}.merge(opts)
|
17
|
-
|
18
|
-
routes.url_for(opts)
|
19
|
-
end
|
20
|
-
end
|
@@ -1,48 +0,0 @@
|
|
1
|
-
module Dorsale::SortingHelper
|
2
|
-
def sortable_column(name, column)
|
3
|
-
unless column.is_a?(Symbol)
|
4
|
-
raise ArgumentError, "invalid column, please use symbol"
|
5
|
-
end
|
6
|
-
|
7
|
-
current_column, current_order = sortable_column_order
|
8
|
-
|
9
|
-
if current_column == column.to_s
|
10
|
-
if current_order == :asc
|
11
|
-
name = "#{name} ↓"
|
12
|
-
new_sort_param = "-#{column}"
|
13
|
-
end
|
14
|
-
|
15
|
-
if current_order == :desc
|
16
|
-
name = "#{name} ↑"
|
17
|
-
new_sort_param = column
|
18
|
-
end
|
19
|
-
|
20
|
-
klass = "sort #{current_order}"
|
21
|
-
else
|
22
|
-
new_sort_param = column
|
23
|
-
klass = "sort"
|
24
|
-
end
|
25
|
-
|
26
|
-
link_to(name, params.merge(sort: new_sort_param), class: klass)
|
27
|
-
end
|
28
|
-
|
29
|
-
def sortable_column_order
|
30
|
-
sort_param = params[:sort].to_s
|
31
|
-
|
32
|
-
if sort_param.present?
|
33
|
-
if sort_param.start_with?("-")
|
34
|
-
column = sort_param[1..-1]
|
35
|
-
order = :desc
|
36
|
-
else
|
37
|
-
column = sort_param
|
38
|
-
order = :asc
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
if block_given?
|
43
|
-
yield(column, order)
|
44
|
-
else
|
45
|
-
[column, order]
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
@@ -1,121 +0,0 @@
|
|
1
|
-
module Dorsale::TextHelper
|
2
|
-
include ::ActionView::Helpers::TextHelper
|
3
|
-
include ::ActionView::Helpers::SanitizeHelper
|
4
|
-
|
5
|
-
def euros(n)
|
6
|
-
currency(n, "€")
|
7
|
-
end
|
8
|
-
|
9
|
-
def currency(n, u)
|
10
|
-
return if n.nil?
|
11
|
-
|
12
|
-
I18n.t("number.currency.format.format")
|
13
|
-
.gsub("%n", number(n))
|
14
|
-
.gsub("%u", u)
|
15
|
-
.gsub(" ", "\u00A0")
|
16
|
-
end
|
17
|
-
|
18
|
-
def percentage(n)
|
19
|
-
return if n.nil?
|
20
|
-
|
21
|
-
(number(n) + " %").gsub(" ", "\u00A0")
|
22
|
-
end
|
23
|
-
|
24
|
-
def number(n)
|
25
|
-
return if n.nil?
|
26
|
-
|
27
|
-
opts = {}
|
28
|
-
|
29
|
-
if n.class.to_s.match(/Float|Decimal/i)
|
30
|
-
opts[:precision] = 2
|
31
|
-
else
|
32
|
-
opts[:precision] = 0
|
33
|
-
end
|
34
|
-
|
35
|
-
opts[:delimiter] = I18n.t("number.format.delimiter")
|
36
|
-
opts[:separator] = I18n.t("number.format.separator")
|
37
|
-
|
38
|
-
number_with_precision(n, opts).gsub(" ", "\u00A0")
|
39
|
-
end
|
40
|
-
|
41
|
-
def date(d)
|
42
|
-
return if d.nil?
|
43
|
-
I18n.l(d)
|
44
|
-
end
|
45
|
-
|
46
|
-
def hours(n)
|
47
|
-
return if n.nil?
|
48
|
-
|
49
|
-
number = number_with_precision(n, precision: 2)
|
50
|
-
text = I18n.t("datetime.prompts.hour").downcase
|
51
|
-
text = text.pluralize if n > 1
|
52
|
-
"#{number} #{text}"
|
53
|
-
end
|
54
|
-
|
55
|
-
def text2html(str)
|
56
|
-
return if str.to_s.blank?
|
57
|
-
|
58
|
-
str = str.gsub("\r", "").strip
|
59
|
-
strip_tags(str).gsub("\n", "<br />").html_safe
|
60
|
-
end
|
61
|
-
|
62
|
-
def lf2br(str)
|
63
|
-
return if str.to_s.blank?
|
64
|
-
|
65
|
-
str.gsub("\r", "").gsub("\n", "<br />").html_safe
|
66
|
-
end
|
67
|
-
|
68
|
-
def info(object, attribute, value_or_options = nil, options = {})
|
69
|
-
if value_or_options.nil?
|
70
|
-
value = object.public_send(attribute)
|
71
|
-
elsif value_or_options.is_a?(Hash)
|
72
|
-
value = object.public_send(attribute)
|
73
|
-
options = value_or_options
|
74
|
-
else
|
75
|
-
value = value_or_options
|
76
|
-
end
|
77
|
-
|
78
|
-
if value.blank?
|
79
|
-
value = options[:default]
|
80
|
-
return if value == :hide
|
81
|
-
end
|
82
|
-
|
83
|
-
label = options[:label] || object.t(attribute)
|
84
|
-
tag = options[:tag] || :div
|
85
|
-
separator = options[:separator] || " : "
|
86
|
-
helper = options[:helper]
|
87
|
-
i18n_key = "#{object.class.to_s.tableize.singularize}/#{attribute}"
|
88
|
-
nested = I18n.t("activerecord.attributes.#{i18n_key}").is_a?(Hash)
|
89
|
-
klass = object.is_a?(Module) ? object : object.class
|
90
|
-
object_type = klass.to_s.split("::").last.underscore
|
91
|
-
|
92
|
-
value = t("yes") if value === true
|
93
|
-
value = t("no") if value === false
|
94
|
-
value = object.t("#{attribute}.#{value}") if nested
|
95
|
-
value = send(helper, value) if helper
|
96
|
-
value = number(value) if value.is_a?(Numeric)
|
97
|
-
value = l(value) if value.is_a?(Time)
|
98
|
-
value = l(value) if value.is_a?(Date)
|
99
|
-
value = value.to_s
|
100
|
-
|
101
|
-
html_label = content_tag(:strong, class: "info-label") { label }
|
102
|
-
span_css_class = "info-value #{object_type}-#{attribute}"
|
103
|
-
html_value = content_tag(:span, class: span_css_class) { value }
|
104
|
-
separator_html = content_tag(:span, class: "info-separator") { separator }
|
105
|
-
|
106
|
-
content_tag(tag, class: "info") do
|
107
|
-
[html_label, separator_html, html_value].join.html_safe
|
108
|
-
end
|
109
|
-
end # def info
|
110
|
-
|
111
|
-
def tags(object)
|
112
|
-
return "" if object.tag_list.empty?
|
113
|
-
|
114
|
-
object.tag_list.map { |tag|
|
115
|
-
content_tag(:span, class: "tag label label-primary"){
|
116
|
-
"#{icon :tag} #{tag}".html_safe
|
117
|
-
}
|
118
|
-
}.join(" ").html_safe
|
119
|
-
end
|
120
|
-
|
121
|
-
end
|
@@ -1,11 +0,0 @@
|
|
1
|
-
# Microtime based uuids to be sortable
|
2
|
-
class Dorsale::SortableUUIDGenerator
|
3
|
-
REGEX_WITH_DASHES = /^([0-9a-f]{8})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{12})$/
|
4
|
-
REGEX_WITHOUT_DASHES = /^([0-9a-f]{8})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{12})$/
|
5
|
-
|
6
|
-
def self.generate
|
7
|
-
prefix = Time.zone.now.strftime("%s%9N").to_i.to_s(16)
|
8
|
-
suffix = SecureRandom.hex(8)
|
9
|
-
(prefix + suffix).gsub(REGEX_WITHOUT_DASHES, '\1-\2-\3-\4-\5')
|
10
|
-
end
|
11
|
-
end
|
@@ -1,15 +0,0 @@
|
|
1
|
-
module Dorsale::ActiveRecordUUIDConcern
|
2
|
-
extend ActiveSupport::Concern
|
3
|
-
|
4
|
-
private
|
5
|
-
|
6
|
-
def assign_default_uuid
|
7
|
-
if id.nil? && self.class.columns_hash["id"].type == :uuid
|
8
|
-
self.id = ::Dorsale::SortableUUIDGenerator.generate
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
included do
|
13
|
-
before_save :assign_default_uuid
|
14
|
-
end
|
15
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
module Dorsale::DefaultValuesConcern
|
2
|
-
extend ActiveSupport::Concern
|
3
|
-
|
4
|
-
def assign_default_values; end
|
5
|
-
|
6
|
-
def assign_default(attribute, value)
|
7
|
-
self.send("#{attribute}=", value) if self.send(attribute).nil?
|
8
|
-
end
|
9
|
-
|
10
|
-
included do
|
11
|
-
after_initialize :assign_default_values
|
12
|
-
end
|
13
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
module Dorsale::ModelI18n
|
2
|
-
extend ActiveSupport::Concern
|
3
|
-
|
4
|
-
def t(*args)
|
5
|
-
self.class.t(*args)
|
6
|
-
end
|
7
|
-
|
8
|
-
def ts
|
9
|
-
self.class.ts
|
10
|
-
end
|
11
|
-
|
12
|
-
class_methods do
|
13
|
-
def t(*args)
|
14
|
-
if args.any?
|
15
|
-
human_attribute_name(*args)
|
16
|
-
else
|
17
|
-
model_name.human
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def ts
|
22
|
-
model_name.human(count: 2)
|
23
|
-
end
|
24
|
-
end # class_methods
|
25
|
-
end # Dorsale::ModelI18n
|