reportable_rails 0.1.4 → 0.1.6
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.
- checksums.yaml +4 -4
- data/README.md +207 -207
- data/Rakefile +6 -6
- data/lib/reportable_rails/errors.rb +3 -3
- data/lib/reportable_rails/models/hours_log.rb +34 -34
- data/lib/reportable_rails/models/report_category.rb +64 -64
- data/lib/reportable_rails/version.rb +1 -1
- metadata +49 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ab2d362e38286bc6003486aaa9434c353f2b4450ec41764f53304e351d5a1854
|
4
|
+
data.tar.gz: 16269d2baa8ffcbe33b50a495a609a7a4135803777e03874c2d1522a01336488
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e6f4bdbd08b88c9f4b7cc04837eb1853069adb28d44f74343e61de7dc3b3cf68432bc27b3c9a8c330613dba20526cbc5f262067c99deabcae175cefe58f3fd5a
|
7
|
+
data.tar.gz: 28ef75d7cb12851b639518b8f8bca7885d40147dab423e0027c9c20fc5f7817321e0c34fb257e71f4d0d9dacbb577ae67a7443c749004e3569c72b35eb326178
|
data/README.md
CHANGED
@@ -1,207 +1,207 @@
|
|
1
|
-
# ReportableRails
|
2
|
-
|
3
|
-
[](https://badge.fury.io/rb/reportable_rails)
|
4
|
-
[](https://github.com/adobocorp/reportable_rails/actions)
|
5
|
-
[](https://github.com/testdouble/standard)
|
6
|
-
[](https://codeclimate.com/github/adobocorp/reportable_rails)
|
7
|
-
[](https://codeclimate.com/github/adobocorp/reportable_rails)
|
8
|
-
[](https://www.ruby-lang.org/en/)
|
9
|
-
|
10
|
-
ReportableRails is a Ruby on Rails gem that provides a flexible reporting system for tracking and managing time-based reports with period management.
|
11
|
-
|
12
|
-
## Installation
|
13
|
-
|
14
|
-
Add this line to your application's Gemfile:
|
15
|
-
|
16
|
-
```ruby
|
17
|
-
gem 'reportable_rails'
|
18
|
-
```
|
19
|
-
|
20
|
-
And then execute:
|
21
|
-
|
22
|
-
```bash
|
23
|
-
$ bundle install
|
24
|
-
```
|
25
|
-
|
26
|
-
## Configuration
|
27
|
-
|
28
|
-
ReportableRails can be configured in an initializer:
|
29
|
-
|
30
|
-
```ruby
|
31
|
-
# config/initializers/reportable_rails.rb
|
32
|
-
ReportableRails.configure do |config|
|
33
|
-
# Set the user class for report ownership (default: 'User')
|
34
|
-
config.user_class = 'User'
|
35
|
-
|
36
|
-
# Configure a callback for when reports are submitted
|
37
|
-
config.report_submitted_callback = ->(report) {
|
38
|
-
# Your custom logic here
|
39
|
-
# For example: NotificationMailer.report_submitted(report).deliver_later
|
40
|
-
}
|
41
|
-
|
42
|
-
# Customize the name of the default category
|
43
|
-
config.default_category_name = 'General' # Defaults to 'Uncategorized'
|
44
|
-
end
|
45
|
-
```
|
46
|
-
|
47
|
-
## Usage
|
48
|
-
|
49
|
-
### Setting Up Models
|
50
|
-
|
51
|
-
ReportableRails provides three main models that can be included in your application:
|
52
|
-
|
53
|
-
```ruby
|
54
|
-
# app/models/time_report.rb
|
55
|
-
class TimeReport < ApplicationRecord
|
56
|
-
include ReportableRails::Models::Report
|
57
|
-
end
|
58
|
-
|
59
|
-
# app/models/report_category.rb
|
60
|
-
class ReportCategory < ApplicationRecord
|
61
|
-
include ReportableRails::Models::ReportCategory
|
62
|
-
end
|
63
|
-
|
64
|
-
# app/models/hours_log.rb
|
65
|
-
class HoursLog < ApplicationRecord
|
66
|
-
include ReportableRails::Models::HoursLog
|
67
|
-
end
|
68
|
-
```
|
69
|
-
|
70
|
-
Each model provides the following functionality:
|
71
|
-
|
72
|
-
#### Report Model
|
73
|
-
- `belongs_to :owner` (user who owns the report)
|
74
|
-
- `belongs_to :report_category` (optional categorization)
|
75
|
-
- `has_many :hours_logs` (time entries for the report)
|
76
|
-
- Period management methods
|
77
|
-
- Report submission handling
|
78
|
-
|
79
|
-
#### Report Category Model
|
80
|
-
- `has_many :reports`
|
81
|
-
- Name and description tracking
|
82
|
-
- Active/inactive status management
|
83
|
-
- Scopes for filtering active categories
|
84
|
-
- Helper methods for finding and managing categories
|
85
|
-
|
86
|
-
#### Hours Log Model
|
87
|
-
- `belongs_to :report`
|
88
|
-
- Hours and date tracking
|
89
|
-
- Period validation
|
90
|
-
- Description management
|
91
|
-
- Methods for checking if hours are in current period
|
92
|
-
|
93
|
-
### Managing Hours Logs
|
94
|
-
|
95
|
-
```ruby
|
96
|
-
# Add hours to a report
|
97
|
-
report.add_hours_log({
|
98
|
-
hours: 8,
|
99
|
-
date: Date.current,
|
100
|
-
description: 'Project work'
|
101
|
-
})
|
102
|
-
|
103
|
-
# Remove hours from a report
|
104
|
-
report.remove_hours_log(hours_log_id)
|
105
|
-
```
|
106
|
-
|
107
|
-
### Period Management
|
108
|
-
|
109
|
-
The gem includes built-in period management with bi-monthly periods (1st-15th and 16th-end of month):
|
110
|
-
|
111
|
-
```ruby
|
112
|
-
# Get current period dates
|
113
|
-
start_date = report.current_period_start_date
|
114
|
-
end_date = report.current_period_end_date
|
115
|
-
|
116
|
-
# Get hours for current period
|
117
|
-
current_hours = report.current_period_hours
|
118
|
-
|
119
|
-
# Submit current period report
|
120
|
-
report.submit_current_period_report!
|
121
|
-
```
|
122
|
-
|
123
|
-
### Report Categories
|
124
|
-
|
125
|
-
Reports can be optionally categorized:
|
126
|
-
|
127
|
-
```ruby
|
128
|
-
report = TimeReport.create!(
|
129
|
-
owner: current_user,
|
130
|
-
report_category: ReportableRails::ReportCategory.find_by(name: 'Project Work')
|
131
|
-
)
|
132
|
-
```
|
133
|
-
|
134
|
-
### Default Category
|
135
|
-
|
136
|
-
ReportableRails automatically manages a default "Uncategorized" category that cannot be deactivated or deleted. You can customize the name of this category in your configuration:
|
137
|
-
|
138
|
-
```ruby
|
139
|
-
ReportableRails.configure do |config|
|
140
|
-
config.default_category_name = 'General' # Defaults to 'Uncategorized'
|
141
|
-
end
|
142
|
-
```
|
143
|
-
|
144
|
-
To access the default category:
|
145
|
-
|
146
|
-
```ruby
|
147
|
-
default_category = ReportCategory.default_category # Returns or creates the default category
|
148
|
-
```
|
149
|
-
|
150
|
-
Reports without a specific category will use this default category. The default category:
|
151
|
-
- Cannot be deactivated
|
152
|
-
- Cannot be deleted
|
153
|
-
- Is automatically created when first accessed
|
154
|
-
|
155
|
-
### Database Setup
|
156
|
-
|
157
|
-
You'll need to create the necessary database tables. Here are the recommended migrations:
|
158
|
-
|
159
|
-
```ruby
|
160
|
-
# Create Reports Table
|
161
|
-
class CreateReports < ActiveRecord::Migration[6.1]
|
162
|
-
def change
|
163
|
-
create_table :reports do |t|
|
164
|
-
t.references :owner, null: false, foreign_key: { to_table: :users }
|
165
|
-
t.references :report_category, foreign_key: true
|
166
|
-
t.timestamps
|
167
|
-
end
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
# Create Report Categories Table
|
172
|
-
class CreateReportCategories < ActiveRecord::Migration[6.1]
|
173
|
-
def change
|
174
|
-
create_table :report_categories do |t|
|
175
|
-
t.string :name, null: false
|
176
|
-
t.text :description
|
177
|
-
t.boolean :active, default: true
|
178
|
-
t.timestamps
|
179
|
-
t.index :name, unique: true
|
180
|
-
end
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
# Create Hours Logs Table
|
185
|
-
class CreateHoursLogs < ActiveRecord::Migration[6.1]
|
186
|
-
def change
|
187
|
-
create_table :hours_logs do |t|
|
188
|
-
t.references :report, null: false, foreign_key: true
|
189
|
-
t.decimal :hours, null: false, precision: 4, scale: 2
|
190
|
-
t.date :date, null: false
|
191
|
-
t.text :description, null: false
|
192
|
-
t.timestamps
|
193
|
-
t.index [:report_id, :date]
|
194
|
-
end
|
195
|
-
end
|
196
|
-
end
|
197
|
-
```
|
198
|
-
|
199
|
-
Run the migrations with:
|
200
|
-
|
201
|
-
```bash
|
202
|
-
$ rails db:migrate
|
203
|
-
```
|
204
|
-
|
205
|
-
## License
|
206
|
-
|
207
|
-
The gem is available as open source under the terms of the MIT License.
|
1
|
+
# ReportableRails
|
2
|
+
|
3
|
+
[](https://badge.fury.io/rb/reportable_rails)
|
4
|
+
[](https://github.com/adobocorp/reportable_rails/actions)
|
5
|
+
[](https://github.com/testdouble/standard)
|
6
|
+
[](https://codeclimate.com/github/adobocorp/reportable_rails)
|
7
|
+
[](https://codeclimate.com/github/adobocorp/reportable_rails)
|
8
|
+
[](https://www.ruby-lang.org/en/)
|
9
|
+
|
10
|
+
ReportableRails is a Ruby on Rails gem that provides a flexible reporting system for tracking and managing time-based reports with period management.
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
|
14
|
+
Add this line to your application's Gemfile:
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
gem 'reportable_rails'
|
18
|
+
```
|
19
|
+
|
20
|
+
And then execute:
|
21
|
+
|
22
|
+
```bash
|
23
|
+
$ bundle install
|
24
|
+
```
|
25
|
+
|
26
|
+
## Configuration
|
27
|
+
|
28
|
+
ReportableRails can be configured in an initializer:
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
# config/initializers/reportable_rails.rb
|
32
|
+
ReportableRails.configure do |config|
|
33
|
+
# Set the user class for report ownership (default: 'User')
|
34
|
+
config.user_class = 'User'
|
35
|
+
|
36
|
+
# Configure a callback for when reports are submitted
|
37
|
+
config.report_submitted_callback = ->(report) {
|
38
|
+
# Your custom logic here
|
39
|
+
# For example: NotificationMailer.report_submitted(report).deliver_later
|
40
|
+
}
|
41
|
+
|
42
|
+
# Customize the name of the default category
|
43
|
+
config.default_category_name = 'General' # Defaults to 'Uncategorized'
|
44
|
+
end
|
45
|
+
```
|
46
|
+
|
47
|
+
## Usage
|
48
|
+
|
49
|
+
### Setting Up Models
|
50
|
+
|
51
|
+
ReportableRails provides three main models that can be included in your application:
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
# app/models/time_report.rb
|
55
|
+
class TimeReport < ApplicationRecord
|
56
|
+
include ReportableRails::Models::Report
|
57
|
+
end
|
58
|
+
|
59
|
+
# app/models/report_category.rb
|
60
|
+
class ReportCategory < ApplicationRecord
|
61
|
+
include ReportableRails::Models::ReportCategory
|
62
|
+
end
|
63
|
+
|
64
|
+
# app/models/hours_log.rb
|
65
|
+
class HoursLog < ApplicationRecord
|
66
|
+
include ReportableRails::Models::HoursLog
|
67
|
+
end
|
68
|
+
```
|
69
|
+
|
70
|
+
Each model provides the following functionality:
|
71
|
+
|
72
|
+
#### Report Model
|
73
|
+
- `belongs_to :owner` (user who owns the report)
|
74
|
+
- `belongs_to :report_category` (optional categorization)
|
75
|
+
- `has_many :hours_logs` (time entries for the report)
|
76
|
+
- Period management methods
|
77
|
+
- Report submission handling
|
78
|
+
|
79
|
+
#### Report Category Model
|
80
|
+
- `has_many :reports`
|
81
|
+
- Name and description tracking
|
82
|
+
- Active/inactive status management
|
83
|
+
- Scopes for filtering active categories
|
84
|
+
- Helper methods for finding and managing categories
|
85
|
+
|
86
|
+
#### Hours Log Model
|
87
|
+
- `belongs_to :report`
|
88
|
+
- Hours and date tracking
|
89
|
+
- Period validation
|
90
|
+
- Description management
|
91
|
+
- Methods for checking if hours are in current period
|
92
|
+
|
93
|
+
### Managing Hours Logs
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
# Add hours to a report
|
97
|
+
report.add_hours_log({
|
98
|
+
hours: 8,
|
99
|
+
date: Date.current,
|
100
|
+
description: 'Project work'
|
101
|
+
})
|
102
|
+
|
103
|
+
# Remove hours from a report
|
104
|
+
report.remove_hours_log(hours_log_id)
|
105
|
+
```
|
106
|
+
|
107
|
+
### Period Management
|
108
|
+
|
109
|
+
The gem includes built-in period management with bi-monthly periods (1st-15th and 16th-end of month):
|
110
|
+
|
111
|
+
```ruby
|
112
|
+
# Get current period dates
|
113
|
+
start_date = report.current_period_start_date
|
114
|
+
end_date = report.current_period_end_date
|
115
|
+
|
116
|
+
# Get hours for current period
|
117
|
+
current_hours = report.current_period_hours
|
118
|
+
|
119
|
+
# Submit current period report
|
120
|
+
report.submit_current_period_report!
|
121
|
+
```
|
122
|
+
|
123
|
+
### Report Categories
|
124
|
+
|
125
|
+
Reports can be optionally categorized:
|
126
|
+
|
127
|
+
```ruby
|
128
|
+
report = TimeReport.create!(
|
129
|
+
owner: current_user,
|
130
|
+
report_category: ReportableRails::ReportCategory.find_by(name: 'Project Work')
|
131
|
+
)
|
132
|
+
```
|
133
|
+
|
134
|
+
### Default Category
|
135
|
+
|
136
|
+
ReportableRails automatically manages a default "Uncategorized" category that cannot be deactivated or deleted. You can customize the name of this category in your configuration:
|
137
|
+
|
138
|
+
```ruby
|
139
|
+
ReportableRails.configure do |config|
|
140
|
+
config.default_category_name = 'General' # Defaults to 'Uncategorized'
|
141
|
+
end
|
142
|
+
```
|
143
|
+
|
144
|
+
To access the default category:
|
145
|
+
|
146
|
+
```ruby
|
147
|
+
default_category = ReportCategory.default_category # Returns or creates the default category
|
148
|
+
```
|
149
|
+
|
150
|
+
Reports without a specific category will use this default category. The default category:
|
151
|
+
- Cannot be deactivated
|
152
|
+
- Cannot be deleted
|
153
|
+
- Is automatically created when first accessed
|
154
|
+
|
155
|
+
### Database Setup
|
156
|
+
|
157
|
+
You'll need to create the necessary database tables. Here are the recommended migrations:
|
158
|
+
|
159
|
+
```ruby
|
160
|
+
# Create Reports Table
|
161
|
+
class CreateReports < ActiveRecord::Migration[6.1]
|
162
|
+
def change
|
163
|
+
create_table :reports do |t|
|
164
|
+
t.references :owner, null: false, foreign_key: { to_table: :users }
|
165
|
+
t.references :report_category, foreign_key: true
|
166
|
+
t.timestamps
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
# Create Report Categories Table
|
172
|
+
class CreateReportCategories < ActiveRecord::Migration[6.1]
|
173
|
+
def change
|
174
|
+
create_table :report_categories do |t|
|
175
|
+
t.string :name, null: false
|
176
|
+
t.text :description
|
177
|
+
t.boolean :active, default: true
|
178
|
+
t.timestamps
|
179
|
+
t.index :name, unique: true
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
# Create Hours Logs Table
|
185
|
+
class CreateHoursLogs < ActiveRecord::Migration[6.1]
|
186
|
+
def change
|
187
|
+
create_table :hours_logs do |t|
|
188
|
+
t.references :report, null: false, foreign_key: true
|
189
|
+
t.decimal :hours, null: false, precision: 4, scale: 2
|
190
|
+
t.date :date, null: false
|
191
|
+
t.text :description, null: false
|
192
|
+
t.timestamps
|
193
|
+
t.index [:report_id, :date]
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
```
|
198
|
+
|
199
|
+
Run the migrations with:
|
200
|
+
|
201
|
+
```bash
|
202
|
+
$ rails db:migrate
|
203
|
+
```
|
204
|
+
|
205
|
+
## License
|
206
|
+
|
207
|
+
The gem is available as open source under the terms of the MIT License.
|
data/Rakefile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
require "bundler/gem_tasks"
|
2
|
-
require "rspec/core/rake_task"
|
3
|
-
|
4
|
-
RSpec::Core::RakeTask.new(:spec)
|
5
|
-
|
6
|
-
task default: :spec
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rspec/core/rake_task"
|
3
|
+
|
4
|
+
RSpec::Core::RakeTask.new(:spec)
|
5
|
+
|
6
|
+
task default: :spec
|
@@ -1,3 +1,3 @@
|
|
1
|
-
module ReportableRails
|
2
|
-
class InvalidPeriodError < StandardError; end
|
3
|
-
end
|
1
|
+
module ReportableRails
|
2
|
+
class InvalidPeriodError < StandardError; end
|
3
|
+
end
|
@@ -1,34 +1,34 @@
|
|
1
|
-
module ReportableRails
|
2
|
-
module Models
|
3
|
-
module HoursLog
|
4
|
-
extend ActiveSupport::Concern
|
5
|
-
|
6
|
-
included do
|
7
|
-
belongs_to :report
|
8
|
-
|
9
|
-
validates :hours, presence: true, numericality: { greater_than: 0, less_than_or_equal_to: 24 }
|
10
|
-
validates :date, presence: true
|
11
|
-
validates :description, presence: true, length: { maximum: 1000 }
|
12
|
-
|
13
|
-
validate :date_within_period
|
14
|
-
|
15
|
-
# Check if the hours log belongs to the current reporting period
|
16
|
-
def current_period?
|
17
|
-
return false unless report && date
|
18
|
-
|
19
|
-
date >= report.current_period_start_date && date <= report.current_period_end_date
|
20
|
-
end
|
21
|
-
|
22
|
-
private
|
23
|
-
|
24
|
-
def date_within_period
|
25
|
-
return unless date && report
|
26
|
-
|
27
|
-
unless date >= report.current_period_start_date && date <= report.current_period_end_date
|
28
|
-
errors.add(:date, "must be within the current reporting period (#{report.current_period_start_date} to #{report.current_period_end_date})")
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
1
|
+
module ReportableRails
|
2
|
+
module Models
|
3
|
+
module HoursLog
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
belongs_to :report
|
8
|
+
|
9
|
+
validates :hours, presence: true, numericality: { greater_than: 0, less_than_or_equal_to: 24 }
|
10
|
+
validates :date, presence: true
|
11
|
+
validates :description, presence: true, length: { maximum: 1000 }
|
12
|
+
|
13
|
+
validate :date_within_period
|
14
|
+
|
15
|
+
# Check if the hours log belongs to the current reporting period
|
16
|
+
def current_period?
|
17
|
+
return false unless report && date
|
18
|
+
|
19
|
+
date >= report.current_period_start_date && date <= report.current_period_end_date
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def date_within_period
|
25
|
+
return unless date && report
|
26
|
+
|
27
|
+
unless date >= report.current_period_start_date && date <= report.current_period_end_date
|
28
|
+
errors.add(:date, "must be within the current reporting period (#{report.current_period_start_date} to #{report.current_period_end_date})")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -1,64 +1,64 @@
|
|
1
|
-
module ReportableRails
|
2
|
-
module Models
|
3
|
-
module ReportCategory
|
4
|
-
extend ActiveSupport::Concern
|
5
|
-
|
6
|
-
included do
|
7
|
-
has_many :reports, dependent: :nullify
|
8
|
-
|
9
|
-
validates :name, presence: true, uniqueness: { case_sensitive: false }
|
10
|
-
validates :description, length: { maximum: 1000 }
|
11
|
-
validates :active, inclusion: { in: [true, false] }
|
12
|
-
validate :prevent_deactivating_default_category
|
13
|
-
|
14
|
-
# Scopes
|
15
|
-
scope :active, -> { where(active: true) }
|
16
|
-
scope :ordered, -> { order(:name) }
|
17
|
-
|
18
|
-
before_validation :set_default_active
|
19
|
-
before_destroy :prevent_destroying_default_category
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def set_default_active
|
24
|
-
self.active = true if active.nil?
|
25
|
-
end
|
26
|
-
|
27
|
-
def prevent_deactivating_default_category
|
28
|
-
if name == ReportableRails.configuration.default_category_name && !active
|
29
|
-
errors.add(:active, "cannot deactivate the default category")
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def prevent_destroying_default_category
|
34
|
-
if name == ReportableRails.configuration.default_category_name
|
35
|
-
errors.add(:base, "cannot delete the default category")
|
36
|
-
throw :abort
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
module ClassMethods
|
42
|
-
# Find or create a category by name
|
43
|
-
def find_or_create_by_name(name, description: nil)
|
44
|
-
find_or_create_by(name: name) do |category|
|
45
|
-
category.description = description if description.present?
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
# Get or create the default category
|
50
|
-
def default_category
|
51
|
-
find_or_create_by_name(ReportableRails.configuration.default_category_name,
|
52
|
-
description: 'Default category for uncategorized reports')
|
53
|
-
end
|
54
|
-
|
55
|
-
# Deactivate a category without deleting it
|
56
|
-
def deactivate(name)
|
57
|
-
return false if name == ReportableRails.configuration.default_category_name
|
58
|
-
category = find_by(name: name)
|
59
|
-
category&.update(active: false)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
1
|
+
module ReportableRails
|
2
|
+
module Models
|
3
|
+
module ReportCategory
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
has_many :reports, dependent: :nullify
|
8
|
+
|
9
|
+
validates :name, presence: true, uniqueness: { case_sensitive: false }
|
10
|
+
validates :description, length: { maximum: 1000 }
|
11
|
+
validates :active, inclusion: { in: [true, false] }
|
12
|
+
validate :prevent_deactivating_default_category
|
13
|
+
|
14
|
+
# Scopes
|
15
|
+
scope :active, -> { where(active: true) }
|
16
|
+
scope :ordered, -> { order(:name) }
|
17
|
+
|
18
|
+
before_validation :set_default_active
|
19
|
+
before_destroy :prevent_destroying_default_category
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def set_default_active
|
24
|
+
self.active = true if active.nil?
|
25
|
+
end
|
26
|
+
|
27
|
+
def prevent_deactivating_default_category
|
28
|
+
if name == ReportableRails.configuration.default_category_name && !active
|
29
|
+
errors.add(:active, "cannot deactivate the default category")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def prevent_destroying_default_category
|
34
|
+
if name == ReportableRails.configuration.default_category_name
|
35
|
+
errors.add(:base, "cannot delete the default category")
|
36
|
+
throw :abort
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
module ClassMethods
|
42
|
+
# Find or create a category by name
|
43
|
+
def find_or_create_by_name(name, description: nil)
|
44
|
+
find_or_create_by(name: name) do |category|
|
45
|
+
category.description = description if description.present?
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Get or create the default category
|
50
|
+
def default_category
|
51
|
+
find_or_create_by_name(ReportableRails.configuration.default_category_name,
|
52
|
+
description: 'Default category for uncategorized reports')
|
53
|
+
end
|
54
|
+
|
55
|
+
# Deactivate a category without deleting it
|
56
|
+
def deactivate(name)
|
57
|
+
return false if name == ReportableRails.configuration.default_category_name
|
58
|
+
category = find_by(name: name)
|
59
|
+
category&.update(active: false)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: reportable_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nicu Listana
|
@@ -13,128 +13,144 @@ dependencies:
|
|
13
13
|
name: rails
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
15
15
|
requirements:
|
16
|
-
- - "
|
17
|
-
- !ruby/object:Gem::Version
|
18
|
-
version: '6.1'
|
19
|
-
type: :runtime
|
20
|
-
prerelease: false
|
21
|
-
version_requirements: !ruby/object:Gem::Requirement
|
22
|
-
requirements:
|
23
|
-
- - ">="
|
16
|
+
- - "~>"
|
24
17
|
- !ruby/object:Gem::Version
|
25
18
|
version: '6.1'
|
26
|
-
- !ruby/object:Gem::Dependency
|
27
|
-
name: active_model_serializers
|
28
|
-
requirement: !ruby/object:Gem::Requirement
|
29
|
-
requirements:
|
30
19
|
- - ">="
|
31
20
|
- !ruby/object:Gem::Version
|
32
|
-
version:
|
21
|
+
version: 6.1.7.10
|
33
22
|
type: :runtime
|
34
23
|
prerelease: false
|
35
24
|
version_requirements: !ruby/object:Gem::Requirement
|
36
25
|
requirements:
|
26
|
+
- - "~>"
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
version: '6.1'
|
37
29
|
- - ">="
|
38
30
|
- !ruby/object:Gem::Version
|
39
|
-
version:
|
31
|
+
version: 6.1.7.10
|
40
32
|
- !ruby/object:Gem::Dependency
|
41
33
|
name: actionview
|
42
34
|
requirement: !ruby/object:Gem::Requirement
|
43
35
|
requirements:
|
44
|
-
- - "
|
36
|
+
- - "~>"
|
45
37
|
- !ruby/object:Gem::Version
|
46
38
|
version: 6.1.0
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: 6.1.7.10
|
47
42
|
type: :runtime
|
48
43
|
prerelease: false
|
49
44
|
version_requirements: !ruby/object:Gem::Requirement
|
50
45
|
requirements:
|
51
|
-
- - "
|
46
|
+
- - "~>"
|
52
47
|
- !ruby/object:Gem::Version
|
53
48
|
version: 6.1.0
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: 6.1.7.10
|
54
52
|
- !ruby/object:Gem::Dependency
|
55
53
|
name: activerecord
|
56
54
|
requirement: !ruby/object:Gem::Requirement
|
57
55
|
requirements:
|
58
|
-
- - "
|
56
|
+
- - "~>"
|
59
57
|
- !ruby/object:Gem::Version
|
60
58
|
version: 6.1.0
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 6.1.7.10
|
61
62
|
type: :runtime
|
62
63
|
prerelease: false
|
63
64
|
version_requirements: !ruby/object:Gem::Requirement
|
64
65
|
requirements:
|
65
|
-
- - "
|
66
|
+
- - "~>"
|
66
67
|
- !ruby/object:Gem::Version
|
67
68
|
version: 6.1.0
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: 6.1.7.10
|
68
72
|
- !ruby/object:Gem::Dependency
|
69
73
|
name: activemodel
|
70
74
|
requirement: !ruby/object:Gem::Requirement
|
71
75
|
requirements:
|
72
|
-
- - "
|
76
|
+
- - "~>"
|
73
77
|
- !ruby/object:Gem::Version
|
74
78
|
version: 6.1.0
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: 6.1.7.10
|
75
82
|
type: :runtime
|
76
83
|
prerelease: false
|
77
84
|
version_requirements: !ruby/object:Gem::Requirement
|
78
85
|
requirements:
|
79
|
-
- - "
|
86
|
+
- - "~>"
|
80
87
|
- !ruby/object:Gem::Version
|
81
88
|
version: 6.1.0
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: 6.1.7.10
|
82
92
|
- !ruby/object:Gem::Dependency
|
83
93
|
name: activesupport
|
84
94
|
requirement: !ruby/object:Gem::Requirement
|
85
95
|
requirements:
|
86
|
-
- - "
|
96
|
+
- - "~>"
|
87
97
|
- !ruby/object:Gem::Version
|
88
98
|
version: 6.1.0
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: 6.1.7.10
|
89
102
|
type: :runtime
|
90
103
|
prerelease: false
|
91
104
|
version_requirements: !ruby/object:Gem::Requirement
|
92
105
|
requirements:
|
93
|
-
- - "
|
106
|
+
- - "~>"
|
94
107
|
- !ruby/object:Gem::Version
|
95
108
|
version: 6.1.0
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: 6.1.7.10
|
96
112
|
- !ruby/object:Gem::Dependency
|
97
|
-
name:
|
113
|
+
name: tzinfo-data
|
98
114
|
requirement: !ruby/object:Gem::Requirement
|
99
115
|
requirements:
|
100
116
|
- - "~>"
|
101
117
|
- !ruby/object:Gem::Version
|
102
|
-
version:
|
118
|
+
version: '1.2023'
|
103
119
|
type: :runtime
|
104
120
|
prerelease: false
|
105
121
|
version_requirements: !ruby/object:Gem::Requirement
|
106
122
|
requirements:
|
107
123
|
- - "~>"
|
108
124
|
- !ruby/object:Gem::Version
|
109
|
-
version:
|
125
|
+
version: '1.2023'
|
110
126
|
- !ruby/object:Gem::Dependency
|
111
|
-
name:
|
127
|
+
name: concurrent-ruby
|
112
128
|
requirement: !ruby/object:Gem::Requirement
|
113
129
|
requirements:
|
114
|
-
- -
|
130
|
+
- - '='
|
115
131
|
- !ruby/object:Gem::Version
|
116
|
-
version:
|
132
|
+
version: 1.3.4
|
117
133
|
type: :runtime
|
118
134
|
prerelease: false
|
119
135
|
version_requirements: !ruby/object:Gem::Requirement
|
120
136
|
requirements:
|
121
|
-
- -
|
137
|
+
- - '='
|
122
138
|
- !ruby/object:Gem::Version
|
123
|
-
version:
|
139
|
+
version: 1.3.4
|
124
140
|
- !ruby/object:Gem::Dependency
|
125
141
|
name: sqlite3
|
126
142
|
requirement: !ruby/object:Gem::Requirement
|
127
143
|
requirements:
|
128
144
|
- - ">="
|
129
145
|
- !ruby/object:Gem::Version
|
130
|
-
version: '
|
146
|
+
version: '1.4'
|
131
147
|
type: :runtime
|
132
148
|
prerelease: false
|
133
149
|
version_requirements: !ruby/object:Gem::Requirement
|
134
150
|
requirements:
|
135
151
|
- - ">="
|
136
152
|
- !ruby/object:Gem::Version
|
137
|
-
version: '
|
153
|
+
version: '1.4'
|
138
154
|
- !ruby/object:Gem::Dependency
|
139
155
|
name: rspec-rails
|
140
156
|
requirement: !ruby/object:Gem::Requirement
|