dcidev_approval 0.0.5 → 0.0.9
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 +93 -1
- data/lib/dcidev_approval.rb +18 -6
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e97350e7fc396ea5b6badf639f46c97c256de119290e7f4cf209a29b55c13fc2
|
4
|
+
data.tar.gz: 32378050bd803f53adf02652f4d5502b871e2ea6ce7aed380970a395d1562761
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 59b9cf658199b5dd33f76c3eb22f6d302718a908f220d986a46d9fe90a28f82b490fbc31993a36193f555cadcd5bed77ef91f73c8276a513af210db61aa7f53b
|
7
|
+
data.tar.gz: f800249db88dacaafadfaa400946f602753c558288e6f0671c25c780de21b3fd4660d4e4954472ec8d1264fde3b3214d9c24dee755284224d2cbb146979d85de
|
data/README.md
CHANGED
@@ -1 +1,93 @@
|
|
1
|
-
|
1
|
+
# Setup
|
2
|
+
##### 1. Add new column named `status` to every model requiring this gem
|
3
|
+
`db/migrate/migration_file.rb`
|
4
|
+
```ruby
|
5
|
+
class AddStatusToProduk < ActiveRecord::Migration[6.0]
|
6
|
+
def change
|
7
|
+
add_column :produk, :status, :string
|
8
|
+
add_column :produk, :change_status, :string
|
9
|
+
end
|
10
|
+
end
|
11
|
+
```
|
12
|
+
`app/models/model.rb`
|
13
|
+
```ruby
|
14
|
+
STATUS = %w[waiting approved rejected].freeze
|
15
|
+
enum status: STATUS.zip(STATUS).to_h, _prefix: true
|
16
|
+
|
17
|
+
CHANGE_STATUS = %w(pending_delete pending_update).freeze
|
18
|
+
enum change_status: CHANGE_STATUS.zip(CHANGE_STATUS).to_h, _prefix: true
|
19
|
+
```
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
##### 2. Format your `Agent` and `Role` with one-many relationship.
|
24
|
+
##### 3. Declare instance method `is_admin?` to `Agent` to find out whether an agent is an admin or not
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
def is_admin?
|
28
|
+
# add your custom logic here
|
29
|
+
self.approved? && ["admin", "super_admin", "checker"].include?(self.try(:roles).try(:first).try(:code))
|
30
|
+
end
|
31
|
+
```
|
32
|
+
|
33
|
+
##### 4. Include the module to every model requiring approval. Or just put it in `ApplicationRecord`
|
34
|
+
`app/models/application_record.rb`
|
35
|
+
```ruby
|
36
|
+
class ApplicationRecord < ActiveRecord::Base
|
37
|
+
include DcidevApproval
|
38
|
+
self.abstract_class = true
|
39
|
+
# ...
|
40
|
+
end
|
41
|
+
```
|
42
|
+
|
43
|
+
# Features
|
44
|
+
* Create: `Model.create_data(declared(params), current_user, bypass)`
|
45
|
+
* Update: `model.edit_data(declared(params), current_user, bypass)`
|
46
|
+
* Delete: `model.delete_data(declared(params), current_user, bypass)`
|
47
|
+
* Approval: `model.approval(declared(params))`
|
48
|
+
* Compare current database value and argument to check if there are any update: `model.changes_present?(params)`
|
49
|
+
* Check approval status: `model.waiting_approval?`, `model.pending_insert?`, `model.pending_update?`, `model.pending_delete?`
|
50
|
+
* Find last lodifier & timestamp: `model.last_modified_by`
|
51
|
+
* Find author: `model.created_by`
|
52
|
+
* Find approval agent & timestamp: `model.last_approved_by`
|
53
|
+
|
54
|
+
Explanation
|
55
|
+
* `declared(params)`: is a hash value from Grape Parameters, plain ruby hash can also be used
|
56
|
+
* `current_user`: the agent responsible for the changes
|
57
|
+
* `bypass`: boolean value to toogle the approval system. If not sent, the default value is `true`
|
58
|
+
|
59
|
+
To track changes peformed to a record, call
|
60
|
+
# Callbacks
|
61
|
+
To execute code before/after the CRUD, include module `DcidevApproval` in `ApplicationRecord` and peform overide and or overload on it's child model.
|
62
|
+
|
63
|
+
`app/models/application_record.rb`
|
64
|
+
```ruby
|
65
|
+
class ApplicationRecord < ActiveRecord::Base
|
66
|
+
include DcidevApproval
|
67
|
+
self.abstract_class = true
|
68
|
+
# ...
|
69
|
+
end
|
70
|
+
```
|
71
|
+
|
72
|
+
`app/models/child_model.rb`
|
73
|
+
```ruby
|
74
|
+
class ChildModel < ApplicationRecord
|
75
|
+
# ...
|
76
|
+
def self.create_data(params, agent, request)
|
77
|
+
super(params, agent, false) do |data|
|
78
|
+
# do something after the record is successfully created
|
79
|
+
# in this case, write an activity log
|
80
|
+
# the data variable will return the created record
|
81
|
+
ActivityLog.write("#{agent.is_admin? || params.bypass ? nil : "Request "} Add #{self.class.to_s}", request, agent, menu, data) if params.log
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def edit_data(params, agent, request)
|
86
|
+
super(params, agent, false) do |_|
|
87
|
+
# do something after the record is successfully edited and require approval
|
88
|
+
end
|
89
|
+
end
|
90
|
+
# ...
|
91
|
+
end
|
92
|
+
|
93
|
+
```
|
data/lib/dcidev_approval.rb
CHANGED
@@ -36,6 +36,18 @@ module DcidevApproval
|
|
36
36
|
self.change_status == "pending_delete"
|
37
37
|
end
|
38
38
|
|
39
|
+
def approved?
|
40
|
+
self.status == "approved" || self.change_status.nil?
|
41
|
+
end
|
42
|
+
|
43
|
+
def rejected?
|
44
|
+
self.status == "rejected"
|
45
|
+
end
|
46
|
+
|
47
|
+
def waiting?
|
48
|
+
self.status == "waiting"
|
49
|
+
end
|
50
|
+
|
39
51
|
def last_modified_by
|
40
52
|
# p self.audit_trail
|
41
53
|
if self.try(:change_status).present? && self.try(:change_status) == 'pending_delete'
|
@@ -44,7 +56,7 @@ module DcidevApproval
|
|
44
56
|
log = self.activity_logs.where("activity LIKE '%edit%'").limit(1).order(created_at: :desc).try(:first)
|
45
57
|
end
|
46
58
|
{
|
47
|
-
modified_by: log.present? ? log.try(:agent).try(:name).to_s + " (#{log.try(:agent).try(:username).to_s} | #{log.try(:agent).try(:roles).try(:first).try(:name)})" :
|
59
|
+
modified_by: log.present? ? log.try(:agent).try(:name).to_s + " (#{log.try(:agent).try(:username).to_s} | #{log.try(:agent).try(:roles).try(:first).try(:name)})" : nil,
|
48
60
|
modified_at: log.present? ? log.try(:created_at) || self.try(:updated_at) || self.try(:created_at) : nil
|
49
61
|
}
|
50
62
|
end
|
@@ -61,7 +73,7 @@ module DcidevApproval
|
|
61
73
|
last_approve = self.activity_logs.where("activity LIKE '%approv%'").limit(1).order(created_at: :desc).try(:first)
|
62
74
|
last_entry = self.activity_logs.last
|
63
75
|
{
|
64
|
-
approved_by: last_approve.try(:id) == last_entry.try(:id) ? last_approve.try(:agent).try(:name).to_s + " (#{
|
76
|
+
approved_by: last_approve.try(:id) == last_entry.try(:id) ? last_approve.try(:agent).try(:name).to_s + " (#{last_approve.try(:agent).try(:username).to_s} | #{last_approve.try(:agent).try(:roles).try(:first).try(:name)})" : nil,
|
65
77
|
approved_at: last_approve.try(:id) == last_entry.try(:id) ? last_approve.try(:created_at) : nil
|
66
78
|
}
|
67
79
|
end
|
@@ -109,7 +121,7 @@ module DcidevApproval
|
|
109
121
|
# ActivityLog.write("#{agent.is_admin? ? nil : "Request "}Edit #{self.class.to_s}", request, agent, menu, self) if params.log
|
110
122
|
end
|
111
123
|
end
|
112
|
-
yield
|
124
|
+
yield self
|
113
125
|
end
|
114
126
|
|
115
127
|
def approval(params)
|
@@ -118,7 +130,7 @@ module DcidevApproval
|
|
118
130
|
elsif params.status == "rejected"
|
119
131
|
self.delete_changes
|
120
132
|
end
|
121
|
-
yield
|
133
|
+
yield self
|
122
134
|
end
|
123
135
|
|
124
136
|
def delete_data(agent, bypass = true)
|
@@ -143,15 +155,15 @@ module DcidevApproval
|
|
143
155
|
data = params.merge!({ status: :approved })
|
144
156
|
d = self.new_from_params(data)
|
145
157
|
raise d.errors.full_messages.join(", ") unless d.save
|
158
|
+
yield d
|
146
159
|
# ActivityLog.write("#{agent.is_admin? ? nil : "Request "} Add #{self.to_s}", request, agent, menu, d) if params.log
|
147
160
|
end
|
148
161
|
else
|
149
162
|
d = self.new_from_params(params)
|
150
163
|
d.status = agent.is_admin? ? :approved : :waiting
|
151
164
|
raise d.errors.full_messages.join(", ") unless d.save
|
152
|
-
|
165
|
+
yield d
|
153
166
|
end
|
154
|
-
yield d
|
155
167
|
end
|
156
168
|
end
|
157
169
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dcidev_approval
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Punto Damar P
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-02-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dcidev_active_record
|
@@ -51,7 +51,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
51
51
|
- !ruby/object:Gem::Version
|
52
52
|
version: '0'
|
53
53
|
requirements: []
|
54
|
-
rubygems_version: 3.
|
54
|
+
rubygems_version: 3.1.2
|
55
55
|
signing_key:
|
56
56
|
specification_version: 4
|
57
57
|
summary: Logic for implementing record changes approval
|