implemented a Maker-Checker workflow for Products, with approval-based updates and product locking to prevent concurrent edits
This commit is contained in:
+10
@@ -39,4 +39,14 @@
|
||||
<include file="parts/2014_add_is_mandatory_to_joint_holders.xml" relativeToChangelogFile="true" />
|
||||
<include file="parts/2015_add_senior_citizen_to_savings_account.xml" relativeToChangelogFile="true" />
|
||||
<include file="parts/2016_add_share_linking_enabled_to_savings_account.xml" relativeToChangelogFile="true" />
|
||||
<include file="parts/2017_add_saving_product_temp_table.xml" relativeToChangelogFile="true" />
|
||||
<include file="parts/2018_fix_saving_product_temp_lock_constraint.xml" relativeToChangelogFile="true" />
|
||||
<include file="parts/2019_add_command_source_link_to_saving_product_temp.xml" relativeToChangelogFile="true" />
|
||||
<include file="parts/2020_generalize_product_temp_table.xml" relativeToChangelogFile="true" />
|
||||
<include file="parts/2021_add_fd_rd_approval_permissions.xml" relativeToChangelogFile="true" />
|
||||
<include file="parts/2022_add_product_checker_permissions.xml" relativeToChangelogFile="true" />
|
||||
<include file="parts/2023_fix_product_approval_permissions.xml" relativeToChangelogFile="true" />
|
||||
<include file="parts/2025_recreate_savings_product_temp_table.xml" relativeToChangelogFile="true" />
|
||||
<include file="parts/2026_add_pending_edit_typed_columns.xml" relativeToChangelogFile="true" />
|
||||
<include file="parts/2027_add_pending_edit_satellite_tables.xml" relativeToChangelogFile="true" />
|
||||
</databaseChangeLog>
|
||||
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
<?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">
|
||||
|
||||
<changeSet author="fineract" id="2017-1">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not>
|
||||
<tableExists tableName="m_savings_product_temp" />
|
||||
</not>
|
||||
</preConditions>
|
||||
<createTable tableName="m_savings_product_temp">
|
||||
<column name="id" type="BIGINT" autoIncrement="true">
|
||||
<constraints primaryKey="true" nullable="false" />
|
||||
</column>
|
||||
<column name="savings_product_id" type="BIGINT">
|
||||
<constraints nullable="false" unique="true" uniqueConstraintName="sp_temp_unq_savings_product_id"
|
||||
foreignKeyName="fk_sp_temp_savings_product_id" references="m_savings_product(id)" />
|
||||
</column>
|
||||
<column name="maker_id" type="BIGINT">
|
||||
<constraints nullable="false" foreignKeyName="fk_sp_temp_maker_id" references="m_appuser(id)" />
|
||||
</column>
|
||||
<column name="checker_id" type="BIGINT">
|
||||
<constraints nullable="true" foreignKeyName="fk_sp_temp_checker_id" references="m_appuser(id)" />
|
||||
</column>
|
||||
<column name="created_on" type="DATETIME">
|
||||
<constraints nullable="false" />
|
||||
</column>
|
||||
<column name="checked_on" type="DATETIME">
|
||||
<constraints nullable="true" />
|
||||
</column>
|
||||
<column name="status" type="VARCHAR(20)" defaultValue="PENDING">
|
||||
<constraints nullable="false" />
|
||||
</column>
|
||||
<column name="reject_reason" type="VARCHAR(500)">
|
||||
<constraints nullable="true" />
|
||||
</column>
|
||||
<column name="proposed_payload_json" type="CLOB">
|
||||
<constraints nullable="false" />
|
||||
</column>
|
||||
</createTable>
|
||||
</changeSet>
|
||||
|
||||
<changeSet author="fineract" id="2017-2">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not>
|
||||
<sqlCheck expectedResult="0">SELECT COUNT(*) FROM m_permission WHERE code = 'APPROVE_SAVINGSPRODUCT'</sqlCheck>
|
||||
</not>
|
||||
</preConditions>
|
||||
<insert tableName="m_permission">
|
||||
<column name="grouping" value="organisation" />
|
||||
<column name="code" value="APPROVE_SAVINGSPRODUCT" />
|
||||
<column name="entity_name" value="SAVINGSPRODUCT" />
|
||||
<column name="action_name" value="APPROVE" />
|
||||
<column name="can_maker_checker" valueBoolean="false" />
|
||||
</insert>
|
||||
<insert tableName="m_permission">
|
||||
<column name="grouping" value="organisation" />
|
||||
<column name="code" value="REJECT_SAVINGSPRODUCT" />
|
||||
<column name="entity_name" value="SAVINGSPRODUCT" />
|
||||
<column name="action_name" value="REJECT" />
|
||||
<column name="can_maker_checker" valueBoolean="false" />
|
||||
</insert>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
<?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">
|
||||
|
||||
<!--
|
||||
The original unique constraint on savings_product_id blocked ANY future edit on a product forever, once a
|
||||
single pending edit had been resolved - because resolved rows are kept (not deleted) for audit history.
|
||||
The lock must only apply while status = PENDING. Unique constraints treat NULL as distinct in both
|
||||
PostgreSQL and MySQL/MariaDB, so a nullable "lock key" column - set to the product id while pending, and
|
||||
cleared back to NULL on approve/reject - gives a correct, cross-database concurrency-safe lock.
|
||||
-->
|
||||
<changeSet author="fineract" id="2018-1">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<columnExists tableName="m_savings_product_temp" columnName="savings_product_id" />
|
||||
<not>
|
||||
<columnExists tableName="m_savings_product_temp" columnName="pending_lock_key" />
|
||||
</not>
|
||||
</preConditions>
|
||||
|
||||
<dropUniqueConstraint tableName="m_savings_product_temp" constraintName="sp_temp_unq_savings_product_id" />
|
||||
|
||||
<addColumn tableName="m_savings_product_temp">
|
||||
<column name="pending_lock_key" type="BIGINT">
|
||||
<constraints nullable="true" />
|
||||
</column>
|
||||
</addColumn>
|
||||
|
||||
<sql>UPDATE m_savings_product_temp SET pending_lock_key = savings_product_id WHERE status = 'PENDING'</sql>
|
||||
|
||||
<addUniqueConstraint tableName="m_savings_product_temp" columnNames="pending_lock_key"
|
||||
constraintName="sp_temp_unq_pending_lock_key" />
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
<?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">
|
||||
|
||||
<!--
|
||||
Links each pending edit to the audit-only m_portfolio_command_source row created for it, so that
|
||||
submit/approve/reject also appear in System -> Audit Trails even though this feature bypasses the native
|
||||
maker-checker execution pipeline.
|
||||
-->
|
||||
<changeSet author="fineract" id="2019-1">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not>
|
||||
<columnExists tableName="m_savings_product_temp" columnName="command_source_id" />
|
||||
</not>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_savings_product_temp">
|
||||
<column name="command_source_id" type="BIGINT">
|
||||
<constraints nullable="true" foreignKeyName="fk_sp_temp_command_source_id"
|
||||
references="m_portfolio_command_source(id)" />
|
||||
</column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
<?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">
|
||||
|
||||
<!--
|
||||
Generalizes m_savings_product_temp (kept as one shared table, per requirement) so it can hold pending edits
|
||||
for Current Account Products (m_current_product) and Share Products (m_share_product) as well as Savings
|
||||
Products (m_savings_product) - not just savings. A single BIGINT "product_id" can't carry a normal FK
|
||||
anymore since it now points at three different tables depending on product_type, so the old FK is dropped
|
||||
(application code, not the DB, is now responsible for referential validity here).
|
||||
|
||||
pending_lock_key changes from BIGINT to VARCHAR because a raw numeric id is no longer unique across product
|
||||
types (e.g. a current account product id=3 and a savings product id=3 must not collide). The new format is
|
||||
"<PRODUCT_TYPE>:<product_id>", e.g. "SAVINGS:3" / "CURRENT:3" / "SHARE:3".
|
||||
-->
|
||||
<changeSet author="fineract" id="2020-1">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not>
|
||||
<columnExists tableName="m_savings_product_temp" columnName="product_type" />
|
||||
</not>
|
||||
</preConditions>
|
||||
|
||||
<addColumn tableName="m_savings_product_temp">
|
||||
<column name="product_type" type="VARCHAR(20)" defaultValue="SAVINGS">
|
||||
<constraints nullable="false" />
|
||||
</column>
|
||||
</addColumn>
|
||||
|
||||
<dropForeignKeyConstraint baseTableName="m_savings_product_temp" constraintName="fk_sp_temp_savings_product_id" />
|
||||
|
||||
<renameColumn tableName="m_savings_product_temp" oldColumnName="savings_product_id" newColumnName="product_id"
|
||||
columnDataType="BIGINT" />
|
||||
|
||||
<dropUniqueConstraint tableName="m_savings_product_temp" constraintName="sp_temp_unq_pending_lock_key" />
|
||||
|
||||
<addColumn tableName="m_savings_product_temp">
|
||||
<column name="pending_lock_key_new" type="VARCHAR(40)">
|
||||
<constraints nullable="true" />
|
||||
</column>
|
||||
</addColumn>
|
||||
<sql dbms="postgresql">UPDATE m_savings_product_temp SET pending_lock_key_new = 'SAVINGS:' || product_id WHERE status = 'PENDING'</sql>
|
||||
<sql dbms="mysql,mariadb">UPDATE m_savings_product_temp SET pending_lock_key_new = CONCAT('SAVINGS:', product_id) WHERE status = 'PENDING'</sql>
|
||||
<dropColumn tableName="m_savings_product_temp" columnName="pending_lock_key" />
|
||||
<renameColumn tableName="m_savings_product_temp" oldColumnName="pending_lock_key_new" newColumnName="pending_lock_key"
|
||||
columnDataType="VARCHAR(40)" />
|
||||
|
||||
<addUniqueConstraint tableName="m_savings_product_temp" columnNames="pending_lock_key"
|
||||
constraintName="sp_temp_unq_pending_lock_key" />
|
||||
</changeSet>
|
||||
|
||||
<changeSet author="fineract" id="2020-2">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not>
|
||||
<sqlCheck expectedResult="0">SELECT COUNT(*) FROM m_permission WHERE code = 'APPROVE_CURRENTPRODUCT'</sqlCheck>
|
||||
</not>
|
||||
</preConditions>
|
||||
<insert tableName="m_permission">
|
||||
<column name="grouping" value="organisation" />
|
||||
<column name="code" value="APPROVE_CURRENTPRODUCT" />
|
||||
<column name="entity_name" value="CURRENTPRODUCT" />
|
||||
<column name="action_name" value="APPROVE" />
|
||||
<column name="can_maker_checker" valueBoolean="false" />
|
||||
</insert>
|
||||
<insert tableName="m_permission">
|
||||
<column name="grouping" value="organisation" />
|
||||
<column name="code" value="REJECT_CURRENTPRODUCT" />
|
||||
<column name="entity_name" value="CURRENTPRODUCT" />
|
||||
<column name="action_name" value="REJECT" />
|
||||
<column name="can_maker_checker" valueBoolean="false" />
|
||||
</insert>
|
||||
<insert tableName="m_permission">
|
||||
<column name="grouping" value="organisation" />
|
||||
<column name="code" value="APPROVE_SHAREPRODUCT" />
|
||||
<column name="entity_name" value="SHAREPRODUCT" />
|
||||
<column name="action_name" value="APPROVE" />
|
||||
<column name="can_maker_checker" valueBoolean="false" />
|
||||
</insert>
|
||||
<insert tableName="m_permission">
|
||||
<column name="grouping" value="organisation" />
|
||||
<column name="code" value="REJECT_SHAREPRODUCT" />
|
||||
<column name="entity_name" value="SHAREPRODUCT" />
|
||||
<column name="action_name" value="REJECT" />
|
||||
<column name="can_maker_checker" valueBoolean="false" />
|
||||
</insert>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
<?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">
|
||||
|
||||
<changeSet author="fineract" id="2021-1">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not>
|
||||
<sqlCheck expectedResult="0">SELECT COUNT(*) FROM m_permission WHERE code = 'APPROVE_FIXEDDEPOSITPRODUCT'</sqlCheck>
|
||||
</not>
|
||||
</preConditions>
|
||||
<insert tableName="m_permission">
|
||||
<column name="grouping" value="organisation" />
|
||||
<column name="code" value="APPROVE_FIXEDDEPOSITPRODUCT" />
|
||||
<column name="entity_name" value="FIXEDDEPOSITPRODUCT" />
|
||||
<column name="action_name" value="APPROVE" />
|
||||
<column name="can_maker_checker" valueBoolean="false" />
|
||||
</insert>
|
||||
<insert tableName="m_permission">
|
||||
<column name="grouping" value="organisation" />
|
||||
<column name="code" value="REJECT_FIXEDDEPOSITPRODUCT" />
|
||||
<column name="entity_name" value="FIXEDDEPOSITPRODUCT" />
|
||||
<column name="action_name" value="REJECT" />
|
||||
<column name="can_maker_checker" valueBoolean="false" />
|
||||
</insert>
|
||||
<insert tableName="m_permission">
|
||||
<column name="grouping" value="organisation" />
|
||||
<column name="code" value="APPROVE_RECURRINGDEPOSITPRODUCT" />
|
||||
<column name="entity_name" value="RECURRINGDEPOSITPRODUCT" />
|
||||
<column name="action_name" value="APPROVE" />
|
||||
<column name="can_maker_checker" valueBoolean="false" />
|
||||
</insert>
|
||||
<insert tableName="m_permission">
|
||||
<column name="grouping" value="organisation" />
|
||||
<column name="code" value="REJECT_RECURRINGDEPOSITPRODUCT" />
|
||||
<column name="entity_name" value="RECURRINGDEPOSITPRODUCT" />
|
||||
<column name="action_name" value="REJECT" />
|
||||
<column name="can_maker_checker" valueBoolean="false" />
|
||||
</insert>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
<?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">
|
||||
|
||||
<!--
|
||||
AuditReadPlatformServiceImpl.retrieveAllEntriesToBeChecked() (backing GET /v1/makercheckers, the "Checker
|
||||
Inbox" tab) shows a pending m_portfolio_command_source row to a "limited" checker only if their role holds
|
||||
a permission whose action_name is "<ACTION>_CHECKER" and entity_name matches the row's entity_name (code
|
||||
convention: "<ACTION>_<ENTITY>_CHECKER", matching how core Fineract permissions like UPDATE_ROLE_CHECKER
|
||||
are seeded). Our custom pending-approval CommandSource rows for product edits (SAVINGSPRODUCT,
|
||||
CURRENTPRODUCT, SHAREPRODUCT, FIXEDDEPOSITPRODUCT, RECURRINGDEPOSITPRODUCT) already satisfy the base
|
||||
status=AWAITING_APPROVAL filter, but without these permission rows a limited checker's role has nothing to
|
||||
match against, so the rows never show up in Checker Inbox - only in our own Pending Product Edits screen.
|
||||
|
||||
UPDATE_SAVINGSPRODUCT_CHECKER already exists as a native Fineract permission, so each row below is its own
|
||||
changeset with its own precondition - one already-existing code must not block inserting the others.
|
||||
-->
|
||||
<changeSet author="fineract" id="2022-1">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="0">SELECT COUNT(*) FROM m_permission WHERE code = 'UPDATE_SAVINGSPRODUCT_CHECKER'</sqlCheck>
|
||||
</preConditions>
|
||||
<insert tableName="m_permission">
|
||||
<column name="grouping" value="organisation" />
|
||||
<column name="code" value="UPDATE_SAVINGSPRODUCT_CHECKER" />
|
||||
<column name="entity_name" value="SAVINGSPRODUCT" />
|
||||
<column name="action_name" value="UPDATE_CHECKER" />
|
||||
<column name="can_maker_checker" valueBoolean="false" />
|
||||
</insert>
|
||||
</changeSet>
|
||||
|
||||
<changeSet author="fineract" id="2022-2">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="0">SELECT COUNT(*) FROM m_permission WHERE code = 'UPDATE_CURRENTPRODUCT_CHECKER'</sqlCheck>
|
||||
</preConditions>
|
||||
<insert tableName="m_permission">
|
||||
<column name="grouping" value="organisation" />
|
||||
<column name="code" value="UPDATE_CURRENTPRODUCT_CHECKER" />
|
||||
<column name="entity_name" value="CURRENTPRODUCT" />
|
||||
<column name="action_name" value="UPDATE_CHECKER" />
|
||||
<column name="can_maker_checker" valueBoolean="false" />
|
||||
</insert>
|
||||
</changeSet>
|
||||
|
||||
<changeSet author="fineract" id="2022-3">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="0">SELECT COUNT(*) FROM m_permission WHERE code = 'UPDATE_SHAREPRODUCT_CHECKER'</sqlCheck>
|
||||
</preConditions>
|
||||
<insert tableName="m_permission">
|
||||
<column name="grouping" value="organisation" />
|
||||
<column name="code" value="UPDATE_SHAREPRODUCT_CHECKER" />
|
||||
<column name="entity_name" value="SHAREPRODUCT" />
|
||||
<column name="action_name" value="UPDATE_CHECKER" />
|
||||
<column name="can_maker_checker" valueBoolean="false" />
|
||||
</insert>
|
||||
</changeSet>
|
||||
|
||||
<changeSet author="fineract" id="2022-4">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="0">SELECT COUNT(*) FROM m_permission WHERE code = 'UPDATE_FIXEDDEPOSITPRODUCT_CHECKER'</sqlCheck>
|
||||
</preConditions>
|
||||
<insert tableName="m_permission">
|
||||
<column name="grouping" value="organisation" />
|
||||
<column name="code" value="UPDATE_FIXEDDEPOSITPRODUCT_CHECKER" />
|
||||
<column name="entity_name" value="FIXEDDEPOSITPRODUCT" />
|
||||
<column name="action_name" value="UPDATE_CHECKER" />
|
||||
<column name="can_maker_checker" valueBoolean="false" />
|
||||
</insert>
|
||||
</changeSet>
|
||||
|
||||
<changeSet author="fineract" id="2022-5">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="0">SELECT COUNT(*) FROM m_permission WHERE code = 'UPDATE_RECURRINGDEPOSITPRODUCT_CHECKER'</sqlCheck>
|
||||
</preConditions>
|
||||
<insert tableName="m_permission">
|
||||
<column name="grouping" value="organisation" />
|
||||
<column name="code" value="UPDATE_RECURRINGDEPOSITPRODUCT_CHECKER" />
|
||||
<column name="entity_name" value="RECURRINGDEPOSITPRODUCT" />
|
||||
<column name="action_name" value="UPDATE_CHECKER" />
|
||||
<column name="can_maker_checker" valueBoolean="false" />
|
||||
</insert>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
+165
@@ -0,0 +1,165 @@
|
||||
<?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">
|
||||
|
||||
<!--
|
||||
Changesets 2017-2, 2020-2 and 2021-1 used an inverted precondition - `<not><sqlCheck expectedResult="0">...`
|
||||
actually means "run only if the row ALREADY exists", the opposite of the intended idempotent-insert guard.
|
||||
On a fresh database (count=0) that precondition evaluates to false, so onFail="MARK_RAN" silently skipped
|
||||
the insert entirely - the APPROVE_*/REJECT_* permissions for all five product types were marked as applied
|
||||
in databasechangelog but never actually inserted. Those changesets are already recorded and must not be
|
||||
edited (Liquibase would fail on checksum mismatch), so this migration re-inserts the missing rows under
|
||||
fresh changeset ids, each with a correct (non-inverted) precondition and split per row so one already-
|
||||
existing code can never block the others.
|
||||
-->
|
||||
<changeSet author="fineract" id="2023-1">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="0">SELECT COUNT(*) FROM m_permission WHERE code = 'APPROVE_SAVINGSPRODUCT'</sqlCheck>
|
||||
</preConditions>
|
||||
<insert tableName="m_permission">
|
||||
<column name="grouping" value="organisation" />
|
||||
<column name="code" value="APPROVE_SAVINGSPRODUCT" />
|
||||
<column name="entity_name" value="SAVINGSPRODUCT" />
|
||||
<column name="action_name" value="APPROVE" />
|
||||
<column name="can_maker_checker" valueBoolean="false" />
|
||||
</insert>
|
||||
</changeSet>
|
||||
|
||||
<changeSet author="fineract" id="2023-2">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="0">SELECT COUNT(*) FROM m_permission WHERE code = 'REJECT_SAVINGSPRODUCT'</sqlCheck>
|
||||
</preConditions>
|
||||
<insert tableName="m_permission">
|
||||
<column name="grouping" value="organisation" />
|
||||
<column name="code" value="REJECT_SAVINGSPRODUCT" />
|
||||
<column name="entity_name" value="SAVINGSPRODUCT" />
|
||||
<column name="action_name" value="REJECT" />
|
||||
<column name="can_maker_checker" valueBoolean="false" />
|
||||
</insert>
|
||||
</changeSet>
|
||||
|
||||
<changeSet author="fineract" id="2023-3">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="0">SELECT COUNT(*) FROM m_permission WHERE code = 'APPROVE_CURRENTPRODUCT'</sqlCheck>
|
||||
</preConditions>
|
||||
<insert tableName="m_permission">
|
||||
<column name="grouping" value="organisation" />
|
||||
<column name="code" value="APPROVE_CURRENTPRODUCT" />
|
||||
<column name="entity_name" value="CURRENTPRODUCT" />
|
||||
<column name="action_name" value="APPROVE" />
|
||||
<column name="can_maker_checker" valueBoolean="false" />
|
||||
</insert>
|
||||
</changeSet>
|
||||
|
||||
<changeSet author="fineract" id="2023-4">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="0">SELECT COUNT(*) FROM m_permission WHERE code = 'REJECT_CURRENTPRODUCT'</sqlCheck>
|
||||
</preConditions>
|
||||
<insert tableName="m_permission">
|
||||
<column name="grouping" value="organisation" />
|
||||
<column name="code" value="REJECT_CURRENTPRODUCT" />
|
||||
<column name="entity_name" value="CURRENTPRODUCT" />
|
||||
<column name="action_name" value="REJECT" />
|
||||
<column name="can_maker_checker" valueBoolean="false" />
|
||||
</insert>
|
||||
</changeSet>
|
||||
|
||||
<changeSet author="fineract" id="2023-5">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="0">SELECT COUNT(*) FROM m_permission WHERE code = 'APPROVE_SHAREPRODUCT'</sqlCheck>
|
||||
</preConditions>
|
||||
<insert tableName="m_permission">
|
||||
<column name="grouping" value="organisation" />
|
||||
<column name="code" value="APPROVE_SHAREPRODUCT" />
|
||||
<column name="entity_name" value="SHAREPRODUCT" />
|
||||
<column name="action_name" value="APPROVE" />
|
||||
<column name="can_maker_checker" valueBoolean="false" />
|
||||
</insert>
|
||||
</changeSet>
|
||||
|
||||
<changeSet author="fineract" id="2023-6">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="0">SELECT COUNT(*) FROM m_permission WHERE code = 'REJECT_SHAREPRODUCT'</sqlCheck>
|
||||
</preConditions>
|
||||
<insert tableName="m_permission">
|
||||
<column name="grouping" value="organisation" />
|
||||
<column name="code" value="REJECT_SHAREPRODUCT" />
|
||||
<column name="entity_name" value="SHAREPRODUCT" />
|
||||
<column name="action_name" value="REJECT" />
|
||||
<column name="can_maker_checker" valueBoolean="false" />
|
||||
</insert>
|
||||
</changeSet>
|
||||
|
||||
<changeSet author="fineract" id="2023-7">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="0">SELECT COUNT(*) FROM m_permission WHERE code = 'APPROVE_FIXEDDEPOSITPRODUCT'</sqlCheck>
|
||||
</preConditions>
|
||||
<insert tableName="m_permission">
|
||||
<column name="grouping" value="organisation" />
|
||||
<column name="code" value="APPROVE_FIXEDDEPOSITPRODUCT" />
|
||||
<column name="entity_name" value="FIXEDDEPOSITPRODUCT" />
|
||||
<column name="action_name" value="APPROVE" />
|
||||
<column name="can_maker_checker" valueBoolean="false" />
|
||||
</insert>
|
||||
</changeSet>
|
||||
|
||||
<changeSet author="fineract" id="2023-8">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="0">SELECT COUNT(*) FROM m_permission WHERE code = 'REJECT_FIXEDDEPOSITPRODUCT'</sqlCheck>
|
||||
</preConditions>
|
||||
<insert tableName="m_permission">
|
||||
<column name="grouping" value="organisation" />
|
||||
<column name="code" value="REJECT_FIXEDDEPOSITPRODUCT" />
|
||||
<column name="entity_name" value="FIXEDDEPOSITPRODUCT" />
|
||||
<column name="action_name" value="REJECT" />
|
||||
<column name="can_maker_checker" valueBoolean="false" />
|
||||
</insert>
|
||||
</changeSet>
|
||||
|
||||
<changeSet author="fineract" id="2023-9">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="0">SELECT COUNT(*) FROM m_permission WHERE code = 'APPROVE_RECURRINGDEPOSITPRODUCT'</sqlCheck>
|
||||
</preConditions>
|
||||
<insert tableName="m_permission">
|
||||
<column name="grouping" value="organisation" />
|
||||
<column name="code" value="APPROVE_RECURRINGDEPOSITPRODUCT" />
|
||||
<column name="entity_name" value="RECURRINGDEPOSITPRODUCT" />
|
||||
<column name="action_name" value="APPROVE" />
|
||||
<column name="can_maker_checker" valueBoolean="false" />
|
||||
</insert>
|
||||
</changeSet>
|
||||
|
||||
<changeSet author="fineract" id="2023-10">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="0">SELECT COUNT(*) FROM m_permission WHERE code = 'REJECT_RECURRINGDEPOSITPRODUCT'</sqlCheck>
|
||||
</preConditions>
|
||||
<insert tableName="m_permission">
|
||||
<column name="grouping" value="organisation" />
|
||||
<column name="code" value="REJECT_RECURRINGDEPOSITPRODUCT" />
|
||||
<column name="entity_name" value="RECURRINGDEPOSITPRODUCT" />
|
||||
<column name="action_name" value="REJECT" />
|
||||
<column name="can_maker_checker" valueBoolean="false" />
|
||||
</insert>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
<?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">
|
||||
|
||||
<!--
|
||||
m_savings_product_temp was dropped by an experimental changeset that was later removed from source without
|
||||
restoring the table. Recreates it with the final shape from the 2017/2018/2019/2020 migrations (guarded so
|
||||
it's a no-op wherever the table already exists) so ProductPendingEditRepository and the isPendingApproval
|
||||
subqueries in the product read services stop failing with "relation does not exist".
|
||||
-->
|
||||
<changeSet author="fineract" id="2025-1">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not>
|
||||
<tableExists tableName="m_savings_product_temp" />
|
||||
</not>
|
||||
</preConditions>
|
||||
<createTable tableName="m_savings_product_temp">
|
||||
<column name="id" type="BIGINT" autoIncrement="true">
|
||||
<constraints primaryKey="true" nullable="false" />
|
||||
</column>
|
||||
<column name="product_id" type="BIGINT">
|
||||
<constraints nullable="false" />
|
||||
</column>
|
||||
<column name="product_type" type="VARCHAR(20)" defaultValue="SAVINGS">
|
||||
<constraints nullable="false" />
|
||||
</column>
|
||||
<column name="maker_id" type="BIGINT">
|
||||
<constraints nullable="false" foreignKeyName="fk_sp_temp_maker_id" references="m_appuser(id)" />
|
||||
</column>
|
||||
<column name="checker_id" type="BIGINT">
|
||||
<constraints nullable="true" foreignKeyName="fk_sp_temp_checker_id" references="m_appuser(id)" />
|
||||
</column>
|
||||
<column name="created_on" type="DATETIME">
|
||||
<constraints nullable="false" />
|
||||
</column>
|
||||
<column name="checked_on" type="DATETIME">
|
||||
<constraints nullable="true" />
|
||||
</column>
|
||||
<column name="status" type="VARCHAR(20)" defaultValue="PENDING">
|
||||
<constraints nullable="false" />
|
||||
</column>
|
||||
<column name="reject_reason" type="VARCHAR(500)">
|
||||
<constraints nullable="true" />
|
||||
</column>
|
||||
<column name="proposed_payload_json" type="CLOB">
|
||||
<constraints nullable="false" />
|
||||
</column>
|
||||
<column name="pending_lock_key" type="VARCHAR(40)">
|
||||
<constraints nullable="true" unique="true" uniqueConstraintName="sp_temp_unq_pending_lock_key" />
|
||||
</column>
|
||||
<column name="command_source_id" type="BIGINT">
|
||||
<constraints nullable="true" foreignKeyName="fk_sp_temp_command_source_id"
|
||||
references="m_portfolio_command_source(id)" />
|
||||
</column>
|
||||
</createTable>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
+261
@@ -0,0 +1,261 @@
|
||||
<?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">
|
||||
|
||||
<!--
|
||||
Adds typed columns to m_savings_product_temp so a pending product edit is stored as real,
|
||||
individually-inspectable columns instead of only the opaque proposed_payload_json blob.
|
||||
proposed_payload_json is kept (still written) for a safe deprecation window; nothing here
|
||||
removes or alters any existing column. Every changeset is purely additive (addColumn only)
|
||||
and guarded with a correctly-shaped precondition (<not><columnExists .../></not> - a
|
||||
boolean precondition, unlike the historical bug in 2017-2/2020-2 which wrapped a numeric
|
||||
<sqlCheck expectedResult="0"> in <not>, inverting its meaning).
|
||||
|
||||
Columns are grouped by which product type(s) apply them; unrelated columns are simply NULL
|
||||
for a given row's product_type. Names are the snake_case of the JSON API parameter name the
|
||||
column stores, not the source product table's own column name, since this table stores
|
||||
proposed *edits* (parameter values), not a mirror of product-table storage.
|
||||
-->
|
||||
|
||||
<!-- Group 1: fields shared across Savings, Current, FD and RD (FD/RD extend Savings) -->
|
||||
<changeSet author="fineract" id="2026-1">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not>
|
||||
<columnExists tableName="m_savings_product_temp" columnName="name" />
|
||||
</not>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_savings_product_temp">
|
||||
<column name="name" type="VARCHAR(100)" />
|
||||
<column name="short_name" type="VARCHAR(20)" />
|
||||
<column name="description" type="VARCHAR(500)" />
|
||||
<column name="currency_code" type="VARCHAR(3)" />
|
||||
<column name="digits_after_decimal" type="INTEGER" />
|
||||
<column name="in_multiples_of" type="INTEGER" />
|
||||
<column name="accounting_rule" type="INTEGER" />
|
||||
|
||||
<column name="nominal_annual_interest_rate" type="DECIMAL(19,6)" />
|
||||
<column name="interest_compounding_period_type" type="INTEGER" />
|
||||
<column name="interest_posting_period_type" type="INTEGER" />
|
||||
<column name="interest_calculation_type" type="INTEGER" />
|
||||
<column name="interest_calculation_days_in_year_type" type="INTEGER" />
|
||||
<column name="min_required_opening_balance" type="DECIMAL(19,6)" />
|
||||
<column name="lockin_period_frequency" type="INTEGER" />
|
||||
<column name="lockin_period_frequency_type" type="INTEGER" />
|
||||
<column name="withdrawal_fee_for_transfers" type="BOOLEAN" />
|
||||
<column name="allow_overdraft" type="BOOLEAN" />
|
||||
<column name="overdraft_limit" type="DECIMAL(19,6)" />
|
||||
<column name="nominal_annual_interest_rate_overdraft" type="DECIMAL(19,6)" />
|
||||
<column name="min_overdraft_for_interest_calculation" type="DECIMAL(19,6)" />
|
||||
<column name="enforce_min_required_balance" type="BOOLEAN" />
|
||||
<column name="min_required_balance" type="DECIMAL(19,6)" />
|
||||
<column name="lien_allowed" type="BOOLEAN" />
|
||||
<column name="max_allowed_lien_limit" type="DECIMAL(19,6)" />
|
||||
<column name="min_balance_for_interest_calculation" type="DECIMAL(19,6)" />
|
||||
<column name="with_hold_tax" type="BOOLEAN" />
|
||||
<column name="tax_group_id" type="BIGINT" />
|
||||
<column name="other_gl_mappings" type="CLOB" />
|
||||
<column name="is_dormancy_tracking_active" type="BOOLEAN" />
|
||||
<column name="days_to_inactive" type="INTEGER" />
|
||||
<column name="days_to_dormancy" type="INTEGER" />
|
||||
<column name="days_to_escheat" type="INTEGER" />
|
||||
<column name="account_type" type="VARCHAR(50)" />
|
||||
<column name="customer_segment" type="VARCHAR(50)" />
|
||||
<column name="product_code" type="VARCHAR(20)" />
|
||||
<column name="gl_account_id" type="BIGINT" />
|
||||
<column name="effective_date" type="DATE" />
|
||||
<column name="effective_to" type="DATE" />
|
||||
<column name="end_date" type="DATE" />
|
||||
<column name="introducer_required" type="BOOLEAN" />
|
||||
<column name="share_linking_enabled" type="BOOLEAN" />
|
||||
<column name="nomination_facility" type="BOOLEAN" />
|
||||
<column name="dormancy_alert" type="BOOLEAN" />
|
||||
<column name="interest_calculate_selector" type="INTEGER" />
|
||||
<column name="average_period" type="VARCHAR(20)" />
|
||||
<column name="auto_post" type="BOOLEAN" />
|
||||
<column name="frequency_fix_day" type="INTEGER" />
|
||||
<column name="last_interest_date" type="DATE" />
|
||||
<column name="enable_lockin_period" type="BOOLEAN" />
|
||||
<column name="balance_frequency" type="VARCHAR(50)" />
|
||||
<column name="account_closed_zero_balance_in_day_closing" type="BOOLEAN" />
|
||||
<column name="balance_swap_option" type="BOOLEAN" />
|
||||
<column name="msme" type="BOOLEAN" />
|
||||
<column name="auto_debit_facility" type="BOOLEAN" />
|
||||
<column name="loan_facility" type="BOOLEAN" />
|
||||
<column name="premature_withdrawal_option" type="BOOLEAN" />
|
||||
<column name="tenure_flexibility" type="BOOLEAN" />
|
||||
<column name="lien_marked" type="BOOLEAN" />
|
||||
<column name="maturity_instructions" type="BOOLEAN" />
|
||||
<column name="credit_maturity_proceeds" type="BOOLEAN" />
|
||||
<column name="penalty_grace_period_missed_installments" type="BOOLEAN" />
|
||||
<column name="panel_request_applicable" type="BOOLEAN" />
|
||||
<column name="no_penalty_nominee_heir_closure" type="BOOLEAN" />
|
||||
<column name="deceased_settlement" type="BOOLEAN" />
|
||||
<column name="allow_debit_txn_after_due_date" type="BOOLEAN" />
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<!-- Group 2: Current-product-only fields -->
|
||||
<changeSet author="fineract" id="2026-2">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not>
|
||||
<columnExists tableName="m_savings_product_temp" columnName="avg_balance_calc_period" />
|
||||
</not>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_savings_product_temp">
|
||||
<column name="avg_balance_calc_period" type="VARCHAR(10)" />
|
||||
<column name="valid_for_period" type="VARCHAR(10)" />
|
||||
<column name="od_account_closed_zero_balance_in_day_closing" type="BOOLEAN" />
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<!-- Group 3: Share-product-only fields -->
|
||||
<changeSet author="fineract" id="2026-3">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not>
|
||||
<columnExists tableName="m_savings_product_temp" columnName="total_shares" />
|
||||
</not>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_savings_product_temp">
|
||||
<column name="total_shares" type="BIGINT" />
|
||||
<column name="total_shares_issued" type="BIGINT" />
|
||||
<column name="unit_price" type="DECIMAL(19,6)" />
|
||||
<column name="minimum_shares" type="BIGINT" />
|
||||
<column name="nominal_shares" type="BIGINT" />
|
||||
<column name="maximum_shares" type="BIGINT" />
|
||||
<column name="allow_dividend_calc_for_inactive_clients" type="BOOLEAN" />
|
||||
<column name="minimum_active_period_for_dividends" type="INTEGER" />
|
||||
<column name="minimum_active_period_frequency_type" type="INTEGER" />
|
||||
<column name="share_lockin_period" type="INTEGER" />
|
||||
<column name="share_lockin_period_frequency_type" type="INTEGER" />
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<!-- Group 4: Fixed-Deposit-only fields (also used by Recurring Deposit, which extends FD) -->
|
||||
<changeSet author="fineract" id="2026-4">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not>
|
||||
<columnExists tableName="m_savings_product_temp" columnName="fd_type" />
|
||||
</not>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_savings_product_temp">
|
||||
<column name="fd_type" type="VARCHAR(20)" />
|
||||
<column name="pre_closure_penal_applicable" type="BOOLEAN" />
|
||||
<column name="pre_closure_penal_interest" type="DECIMAL(19,6)" />
|
||||
<column name="pre_closure_penal_interest_on_type_id" type="INTEGER" />
|
||||
<column name="min_deposit_term" type="INTEGER" />
|
||||
<column name="max_deposit_term" type="INTEGER" />
|
||||
<column name="min_deposit_term_type_id" type="INTEGER" />
|
||||
<column name="max_deposit_term_type_id" type="INTEGER" />
|
||||
<column name="in_multiples_of_deposit_term" type="INTEGER" />
|
||||
<column name="in_multiples_of_deposit_term_type_id" type="INTEGER" />
|
||||
<column name="min_deposit_amount" type="DECIMAL(19,6)" />
|
||||
<column name="max_deposit_amount" type="DECIMAL(19,6)" />
|
||||
<column name="deposit_amount" type="DECIMAL(19,6)" />
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<!-- Group 5: Recurring-Deposit-only fields -->
|
||||
<changeSet author="fineract" id="2026-5">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not>
|
||||
<columnExists tableName="m_savings_product_temp" columnName="is_mandatory_deposit" />
|
||||
</not>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_savings_product_temp">
|
||||
<column name="is_mandatory_deposit" type="BOOLEAN" />
|
||||
<column name="allow_withdrawal" type="BOOLEAN" />
|
||||
<column name="adjust_advance_towards_future_payments" type="BOOLEAN" />
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<!-- Group 6: accountFacilityConfig (1:1 today - kept as flat columns, fc_ prefix) -->
|
||||
<changeSet author="fineract" id="2026-6">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not>
|
||||
<columnExists tableName="m_savings_product_temp" columnName="fc_atm_facility" />
|
||||
</not>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_savings_product_temp">
|
||||
<column name="fc_atm_facility" type="BOOLEAN" />
|
||||
<column name="fc_atm_withdrawal_facility" type="BOOLEAN" />
|
||||
<column name="fc_upi_facility" type="BOOLEAN" />
|
||||
<column name="fc_pos_transactions_facility" type="BOOLEAN" />
|
||||
<column name="fc_cheque_book" type="BOOLEAN" />
|
||||
<column name="fc_imps_facility" type="BOOLEAN" />
|
||||
<column name="fc_sms_alerts" type="BOOLEAN" />
|
||||
<column name="fc_bbps_facility" type="BOOLEAN" />
|
||||
<column name="fc_insurance_cover" type="BOOLEAN" />
|
||||
<column name="fc_bepg_facility" type="BOOLEAN" />
|
||||
<column name="fc_neft_facility" type="BOOLEAN" />
|
||||
<column name="fc_rtgs_facility" type="BOOLEAN" />
|
||||
<column name="fc_inter_bank_total_cap_facility" type="BOOLEAN" />
|
||||
<column name="fc_withdrawal_facility" type="BOOLEAN" />
|
||||
<column name="fc_deposit_facility_kyc" type="BOOLEAN" />
|
||||
<column name="fc_virtual_debit_card" type="BOOLEAN" />
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<!-- Group 7: depositLimitKyc (1:1 today - kept as flat columns, kyc_ prefix) -->
|
||||
<changeSet author="fineract" id="2026-7">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not>
|
||||
<columnExists tableName="m_savings_product_temp" columnName="kyc_general_type" />
|
||||
</not>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_savings_product_temp">
|
||||
<column name="kyc_general_type" type="VARCHAR(50)" />
|
||||
<column name="kyc_general_limit" type="VARCHAR(50)" />
|
||||
<column name="kyc_minor_type" type="VARCHAR(50)" />
|
||||
<column name="kyc_minor_limit" type="BIGINT" />
|
||||
<column name="kyc_small_saving_type" type="VARCHAR(50)" />
|
||||
<column name="kyc_small_saving_limit" type="BIGINT" />
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<!-- Group 8: GL account mapping scalar ids (1:1 today - kept as flat columns, gl_ prefix). No FK
|
||||
constraints - the existing validator already checks GL account validity at submit time. -->
|
||||
<changeSet author="fineract" id="2026-8">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not>
|
||||
<columnExists tableName="m_savings_product_temp" columnName="gl_savings_reference_account_id" />
|
||||
</not>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_savings_product_temp">
|
||||
<column name="gl_savings_reference_account_id" type="BIGINT" />
|
||||
<column name="gl_savings_control_account_id" type="BIGINT" />
|
||||
<column name="gl_income_from_fee_account_id" type="BIGINT" />
|
||||
<column name="gl_income_from_penalty_account_id" type="BIGINT" />
|
||||
<column name="gl_interest_on_savings_account_id" type="BIGINT" />
|
||||
<column name="gl_transfers_in_suspense_account_id" type="BIGINT" />
|
||||
<column name="gl_overdraft_portfolio_control_id" type="BIGINT" />
|
||||
<column name="gl_income_from_interest_id" type="BIGINT" />
|
||||
<column name="gl_write_off_account_id" type="BIGINT" />
|
||||
<column name="gl_escheat_liability_id" type="BIGINT" />
|
||||
<column name="gl_penalties_receivable_account_id" type="BIGINT" />
|
||||
<column name="gl_interest_receivable_account_id" type="BIGINT" />
|
||||
<column name="gl_fees_receivable_account_id" type="BIGINT" />
|
||||
<column name="gl_interest_payable_account_id" type="BIGINT" />
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
<?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">
|
||||
|
||||
<!--
|
||||
Satellite tables for the genuine one-to-many pieces of a pending product edit (charges,
|
||||
facility limits, GL array mappings, share market prices) plus a "submitted field" manifest
|
||||
that records which top-level JSON parameters were actually present in the maker's request.
|
||||
|
||||
The manifest table is not optional bookkeeping: raw JSON storage implicitly distinguishes
|
||||
"field omitted" / "field explicitly null" / "field has a value", and every existing
|
||||
command.hasParameter(...) branch in the write-services and assemblers depends on that
|
||||
distinction. Typed nullable columns alone can't represent it, so this table is the
|
||||
relational replacement for that information - one row per parameter name that was present
|
||||
at submit time, per pending edit.
|
||||
|
||||
All tables reference m_savings_product_temp(id) - no cascade delete, since pending-edit
|
||||
rows are never hard-deleted (only status-flipped) once resolved.
|
||||
-->
|
||||
|
||||
<changeSet author="fineract" id="2027-1">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not>
|
||||
<tableExists tableName="m_product_temp_charge" />
|
||||
</not>
|
||||
</preConditions>
|
||||
<createTable tableName="m_product_temp_charge">
|
||||
<column name="id" type="BIGINT" autoIncrement="true">
|
||||
<constraints primaryKey="true" nullable="false" />
|
||||
</column>
|
||||
<column name="pending_edit_id" type="BIGINT">
|
||||
<constraints nullable="false" foreignKeyName="fk_ptc_pending_edit_id" references="m_savings_product_temp(id)" />
|
||||
</column>
|
||||
<column name="charge_id" type="BIGINT">
|
||||
<constraints nullable="false" />
|
||||
</column>
|
||||
</createTable>
|
||||
</changeSet>
|
||||
|
||||
<changeSet author="fineract" id="2027-2">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not>
|
||||
<tableExists tableName="m_product_temp_facility_limit" />
|
||||
</not>
|
||||
</preConditions>
|
||||
<createTable tableName="m_product_temp_facility_limit">
|
||||
<column name="id" type="BIGINT" autoIncrement="true">
|
||||
<constraints primaryKey="true" nullable="false" />
|
||||
</column>
|
||||
<column name="pending_edit_id" type="BIGINT">
|
||||
<constraints nullable="false" foreignKeyName="fk_ptfl_pending_edit_id" references="m_savings_product_temp(id)" />
|
||||
</column>
|
||||
<column name="limit_type" type="VARCHAR(100)">
|
||||
<constraints nullable="false" />
|
||||
</column>
|
||||
<column name="general_limit" type="VARCHAR(50)" />
|
||||
<column name="minor_account_limit" type="VARCHAR(50)" />
|
||||
<column name="small_saving_limit" type="VARCHAR(50)" />
|
||||
</createTable>
|
||||
</changeSet>
|
||||
|
||||
<changeSet author="fineract" id="2027-3">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not>
|
||||
<tableExists tableName="m_product_temp_gl_mapping" />
|
||||
</not>
|
||||
</preConditions>
|
||||
<createTable tableName="m_product_temp_gl_mapping">
|
||||
<column name="id" type="BIGINT" autoIncrement="true">
|
||||
<constraints primaryKey="true" nullable="false" />
|
||||
</column>
|
||||
<column name="pending_edit_id" type="BIGINT">
|
||||
<constraints nullable="false" foreignKeyName="fk_ptgm_pending_edit_id" references="m_savings_product_temp(id)" />
|
||||
</column>
|
||||
<!-- PAYMENT_CHANNEL / FEE / PENALTY -->
|
||||
<column name="mapping_type" type="VARCHAR(30)">
|
||||
<constraints nullable="false" />
|
||||
</column>
|
||||
<column name="payment_type_id" type="BIGINT" />
|
||||
<column name="charge_id" type="BIGINT" />
|
||||
<column name="gl_account_id" type="BIGINT">
|
||||
<constraints nullable="false" />
|
||||
</column>
|
||||
</createTable>
|
||||
</changeSet>
|
||||
|
||||
<changeSet author="fineract" id="2027-4">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not>
|
||||
<tableExists tableName="m_product_temp_share_market_price" />
|
||||
</not>
|
||||
</preConditions>
|
||||
<createTable tableName="m_product_temp_share_market_price">
|
||||
<column name="id" type="BIGINT" autoIncrement="true">
|
||||
<constraints primaryKey="true" nullable="false" />
|
||||
</column>
|
||||
<column name="pending_edit_id" type="BIGINT">
|
||||
<constraints nullable="false" foreignKeyName="fk_ptsmp_pending_edit_id" references="m_savings_product_temp(id)" />
|
||||
</column>
|
||||
<column name="source_id" type="BIGINT" />
|
||||
<column name="delete_flag" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false" />
|
||||
</column>
|
||||
<column name="from_date" type="DATE" />
|
||||
<column name="share_value" type="DECIMAL(19,6)" />
|
||||
</createTable>
|
||||
</changeSet>
|
||||
|
||||
<changeSet author="fineract" id="2027-5">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not>
|
||||
<tableExists tableName="m_product_temp_submitted_field" />
|
||||
</not>
|
||||
</preConditions>
|
||||
<createTable tableName="m_product_temp_submitted_field">
|
||||
<column name="id" type="BIGINT" autoIncrement="true">
|
||||
<constraints primaryKey="true" nullable="false" />
|
||||
</column>
|
||||
<column name="pending_edit_id" type="BIGINT">
|
||||
<constraints nullable="false" foreignKeyName="fk_ptsf_pending_edit_id" references="m_savings_product_temp(id)" />
|
||||
</column>
|
||||
<column name="field_name" type="VARCHAR(100)">
|
||||
<constraints nullable="false" />
|
||||
</column>
|
||||
</createTable>
|
||||
<addUniqueConstraint tableName="m_product_temp_submitted_field" columnNames="pending_edit_id, field_name"
|
||||
constraintName="ptsf_unq_pending_edit_field" />
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
Reference in New Issue
Block a user