feat(delinquency): add maker-checker for Delinquency Ranges and Buckets
Range/bucket create, update and delete now route through the standard command-source approval pipeline, since a bucket drives the SMA/NPA classification of every loan product linked to it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+2
@@ -158,6 +158,8 @@ public class CommandSourceService {
|
|||||||
if ("GLACCOUNT".equalsIgnoreCase(commandSource.getEntityName())
|
if ("GLACCOUNT".equalsIgnoreCase(commandSource.getEntityName())
|
||||||
|| "CBSBASEINTERESTRATE".equalsIgnoreCase(commandSource.getEntityName())
|
|| "CBSBASEINTERESTRATE".equalsIgnoreCase(commandSource.getEntityName())
|
||||||
|| "LOANBASEINTERESTRATE".equalsIgnoreCase(commandSource.getEntityName())
|
|| "LOANBASEINTERESTRATE".equalsIgnoreCase(commandSource.getEntityName())
|
||||||
|
|| "DELINQUENCY_BUCKET".equalsIgnoreCase(commandSource.getEntityName())
|
||||||
|
|| "DELINQUENCY_RANGE".equalsIgnoreCase(commandSource.getEntityName())
|
||||||
|| "CHARGE".equalsIgnoreCase(commandSource.getEntityName())
|
|| "CHARGE".equalsIgnoreCase(commandSource.getEntityName())
|
||||||
|| "LOANPRODUCT".equalsIgnoreCase(commandSource.getEntityName())
|
|| "LOANPRODUCT".equalsIgnoreCase(commandSource.getEntityName())
|
||||||
|| "SAVINGSPRODUCT".equalsIgnoreCase(commandSource.getEntityName())
|
|| "SAVINGSPRODUCT".equalsIgnoreCase(commandSource.getEntityName())
|
||||||
|
|||||||
@@ -621,4 +621,5 @@
|
|||||||
<include file="parts/0581_enable_loan_rate_register_maker_checker.xml" relativeToChangelogFile="true"/>
|
<include file="parts/0581_enable_loan_rate_register_maker_checker.xml" relativeToChangelogFile="true"/>
|
||||||
<include file="parts/0594_loan_rate_register_product_master.xml" relativeToChangelogFile="true"/>
|
<include file="parts/0594_loan_rate_register_product_master.xml" relativeToChangelogFile="true"/>
|
||||||
<include file="parts/0595_seed_loan_rate_register_gl_accounts.xml" relativeToChangelogFile="true"/>
|
<include file="parts/0595_seed_loan_rate_register_gl_accounts.xml" relativeToChangelogFile="true"/>
|
||||||
|
<include file="parts/0596_enable_delinquency_maker_checker.xml" relativeToChangelogFile="true"/>
|
||||||
</databaseChangeLog>
|
</databaseChangeLog>
|
||||||
|
|||||||
+111
@@ -0,0 +1,111 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
|
||||||
|
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Maker-checker on Delinquency Ranges and Buckets (the SMA / NPA classification master).
|
||||||
|
|
||||||
|
A bucket or range feeds the SMA / NPA class of every loan product linked to it, so create, update
|
||||||
|
and delete must not take effect on one person's click. The six commands (CREATE / UPDATE / DELETE on
|
||||||
|
DELINQUENCY_RANGE and DELINQUENCY_BUCKET) are gated with can_maker_checker = true, so each lands in
|
||||||
|
m_portfolio_command_source as PENDING and is applied only when a checker approves it from the
|
||||||
|
Checker Inbox. Each gets a matching *_CHECKER permission, which approving requires.
|
||||||
|
|
||||||
|
Roles: create / update / delete (maker) and the checker permissions go to Super user and the
|
||||||
|
bankadmin user's roles only. UPDATE and DELETE are taken away from every other role. CREATE is left
|
||||||
|
as it is for roles that already hold it. Widen or narrow this later from Admin > Roles.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<changeSet id="0596a_delinquency_maker_checker_permissions" author="cbsnexora" runOnChange="false">
|
||||||
|
<validCheckSum>ANY</validCheckSum>
|
||||||
|
<sql>
|
||||||
|
UPDATE m_permission
|
||||||
|
SET can_maker_checker = TRUE
|
||||||
|
WHERE code IN ('CREATE_DELINQUENCY_RANGE', 'UPDATE_DELINQUENCY_RANGE', 'DELETE_DELINQUENCY_RANGE',
|
||||||
|
'CREATE_DELINQUENCY_BUCKET', 'UPDATE_DELINQUENCY_BUCKET', 'DELETE_DELINQUENCY_BUCKET');
|
||||||
|
|
||||||
|
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||||
|
SELECT 'organisation', v.code, v.entity_name, v.action_name, false
|
||||||
|
FROM (
|
||||||
|
SELECT 'CREATE_DELINQUENCY_RANGE_CHECKER' AS code, 'DELINQUENCY_RANGE' AS entity_name, 'CREATE_CHECKER' AS action_name
|
||||||
|
UNION ALL SELECT 'UPDATE_DELINQUENCY_RANGE_CHECKER', 'DELINQUENCY_RANGE', 'UPDATE_CHECKER'
|
||||||
|
UNION ALL SELECT 'DELETE_DELINQUENCY_RANGE_CHECKER', 'DELINQUENCY_RANGE', 'DELETE_CHECKER'
|
||||||
|
UNION ALL SELECT 'CREATE_DELINQUENCY_BUCKET_CHECKER', 'DELINQUENCY_BUCKET', 'CREATE_CHECKER'
|
||||||
|
UNION ALL SELECT 'UPDATE_DELINQUENCY_BUCKET_CHECKER', 'DELINQUENCY_BUCKET', 'UPDATE_CHECKER'
|
||||||
|
UNION ALL SELECT 'DELETE_DELINQUENCY_BUCKET_CHECKER', 'DELINQUENCY_BUCKET', 'DELETE_CHECKER'
|
||||||
|
) v
|
||||||
|
WHERE NOT EXISTS (SELECT 1 FROM m_permission p WHERE p.code = v.code);
|
||||||
|
</sql>
|
||||||
|
</changeSet>
|
||||||
|
|
||||||
|
<changeSet id="0596b_delinquency_permissions_to_admin_roles_only" author="cbsnexora" runOnChange="false">
|
||||||
|
<validCheckSum>ANY</validCheckSum>
|
||||||
|
<sql>
|
||||||
|
-- Super user: maker + checker for all six commands.
|
||||||
|
INSERT INTO m_role_permission (role_id, permission_id)
|
||||||
|
SELECT r.id, p.id
|
||||||
|
FROM m_role r
|
||||||
|
CROSS JOIN m_permission p
|
||||||
|
WHERE r.name = 'Super user'
|
||||||
|
AND p.entity_name IN ('DELINQUENCY_RANGE', 'DELINQUENCY_BUCKET')
|
||||||
|
AND p.action_name IN ('CREATE', 'UPDATE', 'DELETE', 'CREATE_CHECKER', 'UPDATE_CHECKER', 'DELETE_CHECKER')
|
||||||
|
AND NOT EXISTS (
|
||||||
|
SELECT 1 FROM m_role_permission rp
|
||||||
|
WHERE rp.role_id = r.id AND rp.permission_id = p.id
|
||||||
|
);
|
||||||
|
|
||||||
|
-- bankadmin user's role(s): maker + checker for all six commands.
|
||||||
|
INSERT INTO m_role_permission (role_id, permission_id)
|
||||||
|
SELECT DISTINCT ur.role_id, p.id
|
||||||
|
FROM m_appuser u
|
||||||
|
JOIN m_appuser_role ur ON ur.appuser_id = u.id
|
||||||
|
CROSS JOIN m_permission p
|
||||||
|
WHERE u.username = 'bankadmin'
|
||||||
|
AND p.entity_name IN ('DELINQUENCY_RANGE', 'DELINQUENCY_BUCKET')
|
||||||
|
AND p.action_name IN ('CREATE', 'UPDATE', 'DELETE', 'CREATE_CHECKER', 'UPDATE_CHECKER', 'DELETE_CHECKER')
|
||||||
|
AND NOT EXISTS (
|
||||||
|
SELECT 1 FROM m_role_permission rp
|
||||||
|
WHERE rp.role_id = ur.role_id AND rp.permission_id = p.id
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Every other role loses UPDATE / DELETE on ranges and buckets (and holds no checker permission).
|
||||||
|
DELETE FROM m_role_permission
|
||||||
|
WHERE permission_id IN (
|
||||||
|
SELECT id FROM m_permission
|
||||||
|
WHERE entity_name IN ('DELINQUENCY_RANGE', 'DELINQUENCY_BUCKET')
|
||||||
|
AND action_name IN ('UPDATE', 'DELETE', 'CREATE_CHECKER', 'UPDATE_CHECKER', 'DELETE_CHECKER')
|
||||||
|
)
|
||||||
|
AND role_id NOT IN (
|
||||||
|
SELECT id FROM m_role WHERE name = 'Super user'
|
||||||
|
UNION
|
||||||
|
SELECT ur.role_id
|
||||||
|
FROM m_appuser u
|
||||||
|
JOIN m_appuser_role ur ON ur.appuser_id = u.id
|
||||||
|
WHERE u.username = 'bankadmin'
|
||||||
|
);
|
||||||
|
</sql>
|
||||||
|
</changeSet>
|
||||||
|
|
||||||
|
</databaseChangeLog>
|
||||||
Reference in New Issue
Block a user