Skip to content

Commit 8f9be4e

Browse files
Create script.js
This Business Rule runs 'before' a record is deleted from the 'sn_compliance_policy' table. Its purpose is to prevent a policy from being deleted if it is currently linked to any active controls. This helps maintain data integrity and prevents the creation of orphaned or invalidated compliance records.
1 parent 6750b61 commit 8f9be4e

File tree

1 file changed

+50
-0
lines changed
  • Server-Side Components/Business Rules/Prevent Deletion of Policy with Active Controls

1 file changed

+50
-0
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
(function executeRule(current, previous /*null when async*/ ) {
2+
// This Business Rule runs 'before' a record is deleted from the 'sn_compliance_policy' table.
3+
// Its purpose is to prevent a policy from being deleted if it is currently linked to any active controls.
4+
// This helps maintain data integrity and prevents the creation of orphaned or invalidated compliance records.
5+
6+
7+
// 'sn_compliance_m2m_policy_policy_statement'. This table links policies (via the 'document' field)
8+
// to control statements (via the 'content' field). Using GlideAggregate is more
9+
// performant than GlideRecord for counting records, as it performs the aggregation
10+
// directly in the database.
11+
var grControlAggregate = new GlideAggregate('sn_compliance_m2m_policy_policy_statement');
12+
13+
// Add a query to filter for records in the m2m table where the 'document' field matches
14+
// the sys_id of the policy record currently being deleted.
15+
grControlAggregate.addQuery('document', current.getUniqueValue());
16+
17+
// Add a second query using 'dot-walking' to filter for records where the related
18+
// control statement ('content' field) is currently active. This ensures only active
19+
// controls are considered.
20+
grControlAggregate.addQuery('content.active', true);
21+
22+
// Set the aggregate function to COUNT. This tells the database to return the total
23+
// number of records that match the query conditions.
24+
grControlAggregate.addAggregate('COUNT');
25+
26+
// Execute the database query.
27+
grControlAggregate.query();
28+
29+
// Initialize a variable to store the count of active controls.
30+
var activeControlCount = 0;
31+
32+
// Check if the query returned any results. If it did, retrieve the count.
33+
// Note: GlideAggregate.next() returns a row even if the count is zero.
34+
if (grControlAggregate.next()) {
35+
// Retrieve the aggregated count result and assign it to the variable.
36+
activeControlCount = grControlAggregate.getAggregate('COUNT');
37+
}
38+
39+
// Check if the count of active controls is greater than zero.
40+
if (activeControlCount > 0) {
41+
// If active controls were found, add an error message to display to the user.
42+
// The message includes the count for better clarity.
43+
gs.addErrorMessage('Cannot delete this policy because it has ' + activeControlCount + ' active controls linked to it.');
44+
45+
// This crucial line aborts the current database transaction (the delete operation).
46+
// It prevents the policy record from being deleted.
47+
current.setAbortAction(true);
48+
}
49+
50+
})(current, previous);

0 commit comments

Comments
 (0)