dcidev_approval 0.0.5 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +93 -1
  3. data/lib/dcidev_approval.rb +18 -6
  4. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 23cb421610c1a7d394f5039930b9f039188e3ef8620b663296bfe2fcd33f4e66
4
- data.tar.gz: 05d8d685bd2ccc8d6420c991f0bc77fcfa2e7a516bd1d940de42556e1e8c734b
3
+ metadata.gz: e97350e7fc396ea5b6badf639f46c97c256de119290e7f4cf209a29b55c13fc2
4
+ data.tar.gz: 32378050bd803f53adf02652f4d5502b871e2ea6ce7aed380970a395d1562761
5
5
  SHA512:
6
- metadata.gz: 9df2fd6a8f2cc9f131e816fb47b13defa76cff853da54b6dc21cf9dc74eeaf58ce0d21978bc980635a99330243f26006260fefd6a86c682720fd84da33947081
7
- data.tar.gz: 07675120b1e915524d2e8bf898fc8fe7bd336f10c6ef6bf0eff509975c7593376e378c29a9ea1b70bc376b10367b87e429aa784461d74ced0d4acd34113f312d
6
+ metadata.gz: 59b9cf658199b5dd33f76c3eb22f6d302718a908f220d986a46d9fe90a28f82b490fbc31993a36193f555cadcd5bed77ef91f73c8276a513af210db61aa7f53b
7
+ data.tar.gz: f800249db88dacaafadfaa400946f602753c558288e6f0671c25c780de21b3fd4660d4e4954472ec8d1264fde3b3214d9c24dee755284224d2cbb146979d85de
data/README.md CHANGED
@@ -1 +1,93 @@
1
- dcidev_approval
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
+ ```
@@ -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)})" : "System",
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 + " (#{log.try(:agent).try(:username).to_s} | #{log.try(:agent).try(:roles).try(:first).try(:name)})" : nil,
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 true
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 true
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
- # ActivityLog.write("Add #{self.to_s}", request, agent, menu, d) if params.log
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.5
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-01-31 00:00:00.000000000 Z
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.0.3.1
54
+ rubygems_version: 3.1.2
55
55
  signing_key:
56
56
  specification_version: 4
57
57
  summary: Logic for implementing record changes approval