update some logic show option
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
e212bf7d79
commit
e9a9377148
+113
@@ -0,0 +1,113 @@
|
||||
<!--
|
||||
Copyright since 2025 Mifos Initiative
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<form [formGroup]="savingsAccountSettingsForm">
|
||||
<div class="sps-section">
|
||||
<div class="sps-section__header">
|
||||
<span class="sps-section__badge"><i class="fas fa-balance-scale"></i></span>
|
||||
<span>Balance & Minimum Balance</span>
|
||||
</div>
|
||||
<div class="sps-body">
|
||||
<div class="sps-layout sps-layout--balance">
|
||||
<div class="sps-row sps-row--three">
|
||||
<mat-form-field appearance="outline" class="sps-field sps-field--compact">
|
||||
<mat-label>{{ 'labels.inputs.Minimum Opening Balance' | translate }}</mat-label>
|
||||
<input type="number" matInput formControlName="minRequiredOpeningBalance" min="0" step="0.01" />
|
||||
</mat-form-field>
|
||||
|
||||
<div class="sps-toggle sps-toggle--inline">
|
||||
<mat-checkbox labelPosition="before" formControlName="enforceMinRequiredBalance">
|
||||
<span>Enforce Minimum Balance</span>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
|
||||
<mat-form-field appearance="outline" class="sps-field sps-field--compact">
|
||||
<mat-label>Minimum Balance (₹)</mat-label>
|
||||
<input type="number" matInput formControlName="minRequiredBalance" min="0" step="0.01" />
|
||||
<mat-hint>Penal charge applies on breach</mat-hint>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="sps-row sps-row--two">
|
||||
<mat-form-field appearance="outline" class="sps-field sps-field--compact">
|
||||
<mat-label>Balance Frequency</mat-label>
|
||||
<mat-select formControlName="balanceFrequency">
|
||||
@for (freq of periodFrequencyData; track freq.value) {
|
||||
<mat-option [value]="freq.value">{{ freq.value }}</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<div class="sps-toggle sps-toggle--inline sps-toggle--right">
|
||||
<mat-checkbox labelPosition="before" formControlName="withdrawalFeeForTransfers">
|
||||
<span>{{ 'labels.inputs.Apply Withdrawal Fee for Transfers' | translate }}</span>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sps-section">
|
||||
<div class="sps-section__header">
|
||||
<span class="sps-section__badge"><i class="fas fa-lock"></i></span>
|
||||
<span>Lock-in Period</span>
|
||||
</div>
|
||||
<div class="sps-body">
|
||||
<div class="sps-lockin-row">
|
||||
<span>Enable Lock-in Period</span>
|
||||
<mat-checkbox formControlName="enableLockinPeriod"></mat-checkbox>
|
||||
</div>
|
||||
|
||||
@if (savingsAccountSettingsForm.value.enableLockinPeriod) {
|
||||
<div class="sps-lockin-fields">
|
||||
<mat-form-field appearance="outline" class="sps-field sps-field--compact">
|
||||
<mat-label>{{ 'labels.inputs.Frequency' | translate }}*</mat-label>
|
||||
<input type="number" matInput formControlName="lockinPeriodFrequency" min="1" step="1" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="sps-field sps-field--compact">
|
||||
<mat-label>{{ 'labels.inputs.Type' | translate }}*</mat-label>
|
||||
<mat-select formControlName="lockinPeriodFrequencyType">
|
||||
@for (type of lockinPeriodFrequencyTypeData; track type) {
|
||||
<mat-option [value]="type.id">{{ type.value | translateKey: 'catalogs' }}</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sps-section">
|
||||
<div class="sps-section__header">
|
||||
<span class="sps-section__badge"><i class="fas fa-cog"></i></span>
|
||||
<span>Additional Rules</span>
|
||||
</div>
|
||||
<div class="sps-body">
|
||||
<div class="sps-layout sps-layout--additional">
|
||||
<div class="sps-toggle sps-toggle--full">
|
||||
<mat-checkbox formControlName="accountClosedZeroBalanceInDayClosing">
|
||||
<span>Account Closed with Zero balance in Day Closing</span>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
|
||||
@if (savingsAccountProductTemplate?.minBalanceForInterestCalculation != null) {
|
||||
<mat-form-field appearance="outline" class="sps-field sps-field--compact">
|
||||
<mat-label>{{ 'labels.inputs.Balance Required for Interest Calculation' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
[value]="savingsAccountProductTemplate.minBalanceForInterestCalculation | formatNumber"
|
||||
readonly
|
||||
/>
|
||||
</mat-form-field>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
+169
@@ -0,0 +1,169 @@
|
||||
/**
|
||||
* Copyright since 2025 Mifos Initiative
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
$accent: #0ea5e9;
|
||||
$border: #e2e8f0;
|
||||
$gray-50: #f8f9fa;
|
||||
$gray-200: #e8eaed;
|
||||
$gray-900: #202124;
|
||||
|
||||
.sps-section {
|
||||
border: 1px solid $border;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
|
||||
& + & {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
&__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 12px 24px;
|
||||
background: $gray-50;
|
||||
border-bottom: 1px solid $gray-200;
|
||||
|
||||
i {
|
||||
font-size: 14px;
|
||||
color: $accent;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sps-section__badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 6px;
|
||||
background: #eff6ff;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.sps-body {
|
||||
background: #fff;
|
||||
padding: 18px 24px 24px;
|
||||
}
|
||||
|
||||
.sps-field {
|
||||
width: 100%;
|
||||
|
||||
&--full {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
&--compact {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.sps-layout {
|
||||
display: grid;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.sps-layout--balance {
|
||||
gap: 22px;
|
||||
}
|
||||
|
||||
.sps-layout--additional {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
align-items: start;
|
||||
|
||||
@media (width <= 1100px) {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
.sps-row {
|
||||
display: grid;
|
||||
gap: 18px;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.sps-row--three {
|
||||
grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
|
||||
align-items: center;
|
||||
|
||||
.sps-field--compact:first-child {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.sps-toggle--inline {
|
||||
align-self: center;
|
||||
min-height: 56px;
|
||||
}
|
||||
}
|
||||
|
||||
.sps-row--two {
|
||||
grid-template-columns: minmax(0, 1fr) auto;
|
||||
align-items: center;
|
||||
|
||||
.sps-field--compact {
|
||||
min-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.sps-toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: 56px;
|
||||
|
||||
mat-checkbox {
|
||||
font-size: 14px;
|
||||
color: $gray-900;
|
||||
}
|
||||
|
||||
&--full {
|
||||
min-height: auto;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
&--inline {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
&--right {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
.sps-lockin-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
margin-bottom: 16px;
|
||||
padding-bottom: 16px;
|
||||
border-bottom: 1px solid $gray-200;
|
||||
font-size: 14px;
|
||||
color: $gray-900;
|
||||
}
|
||||
|
||||
.sps-lockin-row mat-checkbox {
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
.sps-lockin-fields {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 16px;
|
||||
|
||||
@media (width <= 640px) {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
/**
|
||||
* Copyright since 2025 Mifos Initiative
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { Component, Input, OnInit, inject } from '@angular/core';
|
||||
import { UntypedFormGroup, UntypedFormBuilder, Validators, UntypedFormControl } from '@angular/forms';
|
||||
import { MatCheckbox } from '@angular/material/checkbox';
|
||||
import { FormatNumberPipe } from '../../../pipes/format-number.pipe';
|
||||
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-savings-account-settings-step',
|
||||
templateUrl: './savings-account-settings-step.component.html',
|
||||
styleUrls: ['./savings-account-settings-step.component.scss'],
|
||||
imports: [
|
||||
...STANDALONE_SHARED_IMPORTS,
|
||||
MatCheckbox,
|
||||
FormatNumberPipe
|
||||
]
|
||||
})
|
||||
export class SavingsAccountSettingsStepComponent implements OnInit {
|
||||
private formBuilder = inject(UntypedFormBuilder);
|
||||
|
||||
private _savingsAccountProductTemplate: any;
|
||||
|
||||
@Input()
|
||||
set savingsAccountProductTemplate(value: any) {
|
||||
this._savingsAccountProductTemplate = value;
|
||||
if (value && this.savingsAccountSettingsForm) {
|
||||
this.applyTemplate(value);
|
||||
}
|
||||
}
|
||||
get savingsAccountProductTemplate(): any {
|
||||
return this._savingsAccountProductTemplate;
|
||||
}
|
||||
|
||||
savingsAccountSettingsForm: UntypedFormGroup;
|
||||
|
||||
lockinPeriodFrequencyTypeData: any[] = [];
|
||||
|
||||
periodFrequencyData: any[] = [
|
||||
{ value: 'Daily' },
|
||||
{ value: 'Weekly' },
|
||||
{ value: 'Monthly' },
|
||||
{ value: 'Quarterly' },
|
||||
{ value: 'Half Yearly' },
|
||||
{ value: 'Yearly' }];
|
||||
|
||||
constructor() {
|
||||
this.createForm();
|
||||
this.buildDependencies();
|
||||
}
|
||||
|
||||
createForm() {
|
||||
this.savingsAccountSettingsForm = this.formBuilder.group({
|
||||
minRequiredOpeningBalance: [''],
|
||||
withdrawalFeeForTransfers: [false],
|
||||
enforceMinRequiredBalance: [false],
|
||||
minRequiredBalance: [''],
|
||||
balanceFrequency: ['Monthly'],
|
||||
enableLockinPeriod: [false],
|
||||
lockinPeriodFrequency: [''],
|
||||
lockinPeriodFrequencyType: [''],
|
||||
accountClosedZeroBalanceInDayClosing: [false],
|
||||
allowOverdraft: [false]
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (this._savingsAccountProductTemplate) {
|
||||
this.applyTemplate(this._savingsAccountProductTemplate);
|
||||
}
|
||||
}
|
||||
|
||||
private applyTemplate(t: any) {
|
||||
this.lockinPeriodFrequencyTypeData = t.lockinPeriodFrequencyTypeOptions || [];
|
||||
const hasLockin = !!(t.lockinPeriodFrequency && t.lockinPeriodFrequency > 0);
|
||||
|
||||
this.savingsAccountSettingsForm.patchValue({
|
||||
minRequiredOpeningBalance: t.minRequiredOpeningBalance,
|
||||
withdrawalFeeForTransfers: t.withdrawalFeeForTransfers || false,
|
||||
enforceMinRequiredBalance: t.enforceMinRequiredBalance || false,
|
||||
minRequiredBalance: t.minRequiredBalance,
|
||||
balanceFrequency: t.balanceFrequency || 'Monthly',
|
||||
enableLockinPeriod: hasLockin,
|
||||
lockinPeriodFrequency: hasLockin ? t.lockinPeriodFrequency : '',
|
||||
lockinPeriodFrequencyType: hasLockin ? t.lockinPeriodFrequencyType?.id || '' : '',
|
||||
accountClosedZeroBalanceInDayClosing: t.accountClosedZeroBalanceInDayClosing || false,
|
||||
allowOverdraft: t.allowOverdraft || false
|
||||
});
|
||||
|
||||
if (t.allowOverdraft) {
|
||||
if (!this.savingsAccountSettingsForm.contains('minOverdraftForInterestCalculation')) {
|
||||
this.savingsAccountSettingsForm.addControl('minOverdraftForInterestCalculation', new UntypedFormControl(''));
|
||||
this.savingsAccountSettingsForm.addControl('nominalAnnualInterestRateOverdraft', new UntypedFormControl(''));
|
||||
this.savingsAccountSettingsForm.addControl('overdraftLimit', new UntypedFormControl(''));
|
||||
}
|
||||
this.savingsAccountSettingsForm.patchValue({
|
||||
minOverdraftForInterestCalculation: t.minOverdraftForInterestCalculation,
|
||||
nominalAnnualInterestRateOverdraft: t.nominalAnnualInterestRateOverdraft,
|
||||
overdraftLimit: t.overdraftLimit
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
buildDependencies() {
|
||||
this.savingsAccountSettingsForm.get('enableLockinPeriod').valueChanges.subscribe((enabled: boolean) => {
|
||||
if (enabled) {
|
||||
this.savingsAccountSettingsForm.get('lockinPeriodFrequency').setValidators([
|
||||
Validators.required,
|
||||
Validators.min(1)
|
||||
]);
|
||||
this.savingsAccountSettingsForm.get('lockinPeriodFrequencyType').setValidators([Validators.required]);
|
||||
} else {
|
||||
this.savingsAccountSettingsForm.get('lockinPeriodFrequency').setValue('');
|
||||
this.savingsAccountSettingsForm.get('lockinPeriodFrequencyType').setValue('');
|
||||
this.savingsAccountSettingsForm.get('lockinPeriodFrequency').clearValidators();
|
||||
this.savingsAccountSettingsForm.get('lockinPeriodFrequencyType').clearValidators();
|
||||
}
|
||||
this.savingsAccountSettingsForm.get('lockinPeriodFrequency').updateValueAndValidity();
|
||||
this.savingsAccountSettingsForm.get('lockinPeriodFrequencyType').updateValueAndValidity();
|
||||
});
|
||||
|
||||
this.savingsAccountSettingsForm.get('allowOverdraft').valueChanges.subscribe((allowed: boolean) => {
|
||||
if (allowed) {
|
||||
this.savingsAccountSettingsForm.addControl('minOverdraftForInterestCalculation', new UntypedFormControl(''));
|
||||
this.savingsAccountSettingsForm.addControl('nominalAnnualInterestRateOverdraft', new UntypedFormControl(''));
|
||||
this.savingsAccountSettingsForm.addControl('overdraftLimit', new UntypedFormControl(''));
|
||||
} else {
|
||||
this.savingsAccountSettingsForm.removeControl('minOverdraftForInterestCalculation');
|
||||
this.savingsAccountSettingsForm.removeControl('nominalAnnualInterestRateOverdraft');
|
||||
this.savingsAccountSettingsForm.removeControl('overdraftLimit');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
get savingsAccountSettings() {
|
||||
const value = { ...this.savingsAccountSettingsForm.getRawValue() };
|
||||
if (!value.enableLockinPeriod) {
|
||||
value.lockinPeriodFrequency = null;
|
||||
value.lockinPeriodFrequencyType = null;
|
||||
}
|
||||
delete value.enableLockinPeriod;
|
||||
delete value.balanceFrequency;
|
||||
delete value.accountClosedZeroBalanceInDayClosing;
|
||||
return value;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user