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
+106
-50
@@ -1,4 +1,4 @@
|
||||
<!--
|
||||
<!--
|
||||
Copyright since 2025 Mifos Initiative
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
@@ -7,63 +7,119 @@
|
||||
-->
|
||||
|
||||
<form [formGroup]="savingsAccountDetailsForm">
|
||||
<div class="layout-row-wrap gap-2px responsive-column">
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-label>{{ 'labels.inputs.Product Name' | translate }}</mat-label>
|
||||
<mat-select formControlName="productId" required>
|
||||
@for (product of productData; track product) {
|
||||
<mat-option [value]="product.id">
|
||||
{{ product.name }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Product Name' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
@if (savingsProductSelected) {
|
||||
<mat-form-field class="flex-48" (click)="submittedOnDatePicker.open()">
|
||||
<mat-label>{{ 'labels.inputs.Submitted On' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
[min]="minDate"
|
||||
[max]="maxDate"
|
||||
[matDatepicker]="submittedOnDatePicker"
|
||||
formControlName="submittedOnDate"
|
||||
required
|
||||
/>
|
||||
<mat-datepicker-toggle matSuffix [for]="submittedOnDatePicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #submittedOnDatePicker></mat-datepicker>
|
||||
<!-- Account Details -->
|
||||
<div class="sad-section">
|
||||
<div class="sad-section__header">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
<h3>Account Details</h3>
|
||||
</div>
|
||||
<div class="sad-grid">
|
||||
<mat-form-field appearance="outline" class="sad-field">
|
||||
<mat-label>{{ 'labels.inputs.Product Name' | translate }}</mat-label>
|
||||
<mat-select formControlName="productId" required>
|
||||
@for (product of productData; track product) {
|
||||
<mat-option [value]="product.id">{{ product.name }}</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Submitted On' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
{{ 'labels.inputs.Product Name' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
}
|
||||
|
||||
@if (savingsProductSelected) {
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-label>{{ 'labels.inputs.Field Officer' | translate }}</mat-label>
|
||||
<mat-select formControlName="fieldOfficerId">
|
||||
@for (officer of fieldOfficerData; track officer) {
|
||||
<mat-option [value]="officer.id">
|
||||
{{ officer.displayName }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
}
|
||||
@if (savingsProductSelected) {
|
||||
<mat-form-field appearance="outline" class="sad-field" (click)="submittedOnDatePicker.open()">
|
||||
<mat-label>{{ 'labels.inputs.Submitted On' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
[min]="minDate"
|
||||
[max]="maxDate"
|
||||
[matDatepicker]="submittedOnDatePicker"
|
||||
formControlName="submittedOnDate"
|
||||
required
|
||||
/>
|
||||
<mat-datepicker-toggle matSuffix [for]="submittedOnDatePicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #submittedOnDatePicker></mat-datepicker>
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Submitted On' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
}
|
||||
|
||||
@if (savingsProductSelected) {
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-label>{{ 'labels.inputs.External ID' | translate }}</mat-label>
|
||||
<input matInput formControlName="externalId" />
|
||||
</mat-form-field>
|
||||
}
|
||||
@if (savingsProductSelected) {
|
||||
<mat-form-field appearance="outline" class="sad-field">
|
||||
<mat-label>{{ 'labels.inputs.Field Officer' | translate }}</mat-label>
|
||||
<mat-select formControlName="fieldOfficerId">
|
||||
@for (officer of fieldOfficerData; track officer) {
|
||||
<mat-option [value]="officer.id">{{ officer.displayName }}</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
}
|
||||
|
||||
@if (savingsProductSelected) {
|
||||
<mat-form-field appearance="outline" class="sad-field">
|
||||
<mat-label>{{ 'labels.inputs.External ID' | translate }}</mat-label>
|
||||
<input matInput formControlName="externalId" />
|
||||
</mat-form-field>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Product Classification (read-only, shown after product is selected) -->
|
||||
@if (savingsProductSelected) {
|
||||
<div class="sad-section sad-section--mt">
|
||||
<div class="sad-section__header">
|
||||
<i class="fas fa-tags"></i>
|
||||
<h3>Product Classification</h3>
|
||||
<span class="sad-badge">From Product</span>
|
||||
</div>
|
||||
<div class="sad-grid sad-grid--classification">
|
||||
<mat-form-field appearance="outline" class="sad-field">
|
||||
<mat-label>Account Type</mat-label>
|
||||
<input matInput [value]="productTemplate.accountType || ''" readonly />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="sad-field">
|
||||
<mat-label>Customer Segment</mat-label>
|
||||
<input matInput [value]="productTemplate.customerSegment || ''" readonly />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="sad-field">
|
||||
<mat-label>Product Code</mat-label>
|
||||
<input matInput [value]="productTemplate.productCode || ''" readonly />
|
||||
</mat-form-field>
|
||||
|
||||
@if (productTemplate.effectiveDate) {
|
||||
<mat-form-field appearance="outline" class="sad-field">
|
||||
<mat-label>Effective Date</mat-label>
|
||||
<input matInput [value]="formatTemplateDate(productTemplate.effectiveDate)" readonly />
|
||||
</mat-form-field>
|
||||
}
|
||||
|
||||
@if (productTemplate.endDate) {
|
||||
<mat-form-field appearance="outline" class="sad-field">
|
||||
<mat-label>End Date</mat-label>
|
||||
<input matInput [value]="formatTemplateDate(productTemplate.endDate)" readonly />
|
||||
</mat-form-field>
|
||||
}
|
||||
|
||||
<mat-form-field appearance="outline" class="sad-field">
|
||||
<mat-label>Introducer Required</mat-label>
|
||||
<input matInput [value]="productTemplate.introducerRequired ? 'Yes' : 'No'" readonly />
|
||||
</mat-form-field>
|
||||
|
||||
<div class="sad-field sad-info-row">
|
||||
<span class="sad-info-label">Share Linking Enabled</span>
|
||||
<span class="sad-badge" [class.sad-badge--yes]="productTemplate.shareLinkingEnabled">
|
||||
{{ productTemplate.shareLinkingEnabled ? 'Yes' : 'No' }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="layout-row align-center gap-2percent margin-t responsive-column">
|
||||
<button mat-raised-button matStepperPrevious disabled>
|
||||
<fa-icon icon="arrow-left" class="m-r-10"></fa-icon>
|
||||
|
||||
+98
@@ -5,3 +5,101 @@
|
||||
* 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;
|
||||
|
||||
.sad-section {
|
||||
border: 1px solid $border;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
|
||||
&--mt {
|
||||
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;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: $gray-900;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sad-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 4px 16px;
|
||||
padding: 16px 24px;
|
||||
|
||||
@media (width <= 600px) {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
.sad-grid--classification {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
|
||||
@media (width <= 900px) {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
@media (width <= 600px) {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
.sad-field {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.sad-info-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
min-height: 56px;
|
||||
}
|
||||
|
||||
.sad-info-label {
|
||||
font-size: 14px;
|
||||
color: $gray-900;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.sad-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 3px 12px;
|
||||
border-radius: 999px;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
background: #dbeafe;
|
||||
color: #1d4ed8;
|
||||
border: 1px solid #bfdbfe;
|
||||
|
||||
&--yes {
|
||||
background: #dcfce7;
|
||||
color: #15803d;
|
||||
border-color: #bbf7d0;
|
||||
}
|
||||
}
|
||||
|
||||
+37
-3
@@ -1,4 +1,4 @@
|
||||
/**
|
||||
/**
|
||||
* Copyright since 2025 Mifos Initiative
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
@@ -7,12 +7,13 @@
|
||||
*/
|
||||
|
||||
/** Angular Imports */
|
||||
import { Component, OnInit, Input, Output, EventEmitter, inject } from '@angular/core';
|
||||
import { Component, OnInit, Input, Output, EventEmitter, inject, ChangeDetectorRef } from '@angular/core';
|
||||
import { UntypedFormGroup, UntypedFormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
|
||||
import { Dates } from 'app/core/utils/dates';
|
||||
import { SettingsService } from 'app/settings/settings.service';
|
||||
|
||||
/** Custom Services */
|
||||
import { SavingsService } from 'app/savings/savings.service';
|
||||
import { SettingsService } from 'app/settings/settings.service';
|
||||
import { MatStepperPrevious, MatStepperNext } from '@angular/material/stepper';
|
||||
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
|
||||
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
||||
@@ -35,6 +36,8 @@ export class SavingsAccountDetailsStepComponent implements OnInit {
|
||||
private formBuilder = inject(UntypedFormBuilder);
|
||||
private savingsService = inject(SavingsService);
|
||||
private settingsService = inject(SettingsService);
|
||||
private dateUtils = inject(Dates);
|
||||
private cdr = inject(ChangeDetectorRef);
|
||||
|
||||
/** Savings Account Template */
|
||||
@Input() savingsAccountTemplate: any;
|
||||
@@ -57,6 +60,9 @@ export class SavingsAccountDetailsStepComponent implements OnInit {
|
||||
/** Savings Account Template with product data */
|
||||
@Output() savingsAccountProductTemplate = new EventEmitter();
|
||||
|
||||
/** Local copy of product template for displaying classification info */
|
||||
productTemplate: any = null;
|
||||
|
||||
/**
|
||||
* Sets share account details form.
|
||||
* @param {FormBuilder} formBuilder Form Builder.
|
||||
@@ -115,9 +121,11 @@ export class SavingsAccountDetailsStepComponent implements OnInit {
|
||||
this.savingsService
|
||||
.getSavingsAccountTemplate(entityId, productId, this.savingsAccountTemplate.groupId ? true : false)
|
||||
.subscribe((response: any) => {
|
||||
this.productTemplate = response;
|
||||
this.savingsAccountProductTemplate.emit(response);
|
||||
this.fieldOfficerData = response.fieldOfficerOptions;
|
||||
this.savingsProductSelected = true;
|
||||
this.cdr.detectChanges();
|
||||
if (!this.isFieldOfficerPatched && this.savingsAccountTemplate.fieldOfficerId) {
|
||||
this.savingsAccountDetailsForm.get('fieldOfficerId').patchValue(this.savingsAccountTemplate.fieldOfficerId);
|
||||
this.isFieldOfficerPatched = true;
|
||||
@@ -128,6 +136,32 @@ export class SavingsAccountDetailsStepComponent implements OnInit {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats template dates into the current CBS date format.
|
||||
* Handles backend date arrays like [2026, 4, 20] as well as strings and Date objects.
|
||||
*/
|
||||
formatTemplateDate(value: any): string {
|
||||
if (!value) {
|
||||
return '';
|
||||
}
|
||||
|
||||
let dateValue: Date | null = null;
|
||||
|
||||
if (value instanceof Date) {
|
||||
dateValue = value;
|
||||
} else if (Array.isArray(value) && value.length >= 3) {
|
||||
dateValue = new Date(value[0], value[1] - 1, value[2]);
|
||||
} else {
|
||||
dateValue = new Date(value);
|
||||
}
|
||||
|
||||
if (!dateValue || Number.isNaN(dateValue.getTime())) {
|
||||
return Array.isArray(value) ? value.join('/') : String(value);
|
||||
}
|
||||
|
||||
return this.dateUtils.formatDate(dateValue, 'M/d/yyyy') || '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns savings account form value.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user