merge angular-17 into dev to upgrade from Angular v16 to v17
This commit is contained in:
+1
-1
@@ -263,7 +263,7 @@ export class CreateStandingInstructionsComponent implements OnInit {
|
||||
/** Refine Object
|
||||
* Removes the object param with null or '' values
|
||||
*/
|
||||
refineObject(dataObj: Object) {
|
||||
refineObject(dataObj: { [key: string]: any }) {
|
||||
const propNames = Object.getOwnPropertyNames(dataObj);
|
||||
for (let i = 0; i < propNames.length; i++) {
|
||||
const propName = propNames[i];
|
||||
|
||||
@@ -43,6 +43,9 @@ export class CenterActionsComponent {
|
||||
) {
|
||||
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
|
||||
const name = this.route.snapshot.params['action'];
|
||||
this.actions[name] = true;
|
||||
|
||||
if (name && name in this.actions) {
|
||||
this.actions[name as keyof typeof this.actions] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ export class ClientActionsComponent {
|
||||
'Accept Transfer': boolean;
|
||||
'Reject Transfer': boolean;
|
||||
Reactivate: boolean;
|
||||
Activate: boolean;
|
||||
'Undo Rejection': boolean;
|
||||
'Add Charge': boolean;
|
||||
'Take Survey': boolean;
|
||||
@@ -41,6 +42,7 @@ export class ClientActionsComponent {
|
||||
'Accept Transfer': false,
|
||||
'Reject Transfer': false,
|
||||
Reactivate: false,
|
||||
Activate: false,
|
||||
'Undo Rejection': false,
|
||||
'Add Charge': false,
|
||||
'Take Survey': false,
|
||||
@@ -57,7 +59,7 @@ export class ClientActionsComponent {
|
||||
private router: Router
|
||||
) {
|
||||
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
|
||||
const name = this.route.snapshot.params['name'];
|
||||
const name = this.route.snapshot.params['name'] as keyof typeof this.actions;
|
||||
this.actions[name] = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ export class TakeSurveyComponent {
|
||||
|
||||
// TODO: document the function
|
||||
groupBy(array: any, func: any) {
|
||||
const groups = {};
|
||||
const groups: { [key: string]: any[] } = {};
|
||||
array.forEach((ele: any) => {
|
||||
const group = JSON.stringify(func(ele));
|
||||
groups[group] = groups[group] || [];
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@
|
||||
</mat-form-field>
|
||||
|
||||
<mat-checkbox formControlName="isDependent" labelPosition="before" class="flex-50-minus-25px">
|
||||
>{{ 'labels.inputs.Is Dependent' | translate }}?
|
||||
{{ 'labels.inputs.Is Dependent' | translate }}?
|
||||
</mat-checkbox>
|
||||
|
||||
<mat-form-field class="flex-50-minus-25px">
|
||||
|
||||
+25
-3
@@ -52,7 +52,10 @@ export class IndividualCollectionSheetComponent implements OnInit {
|
||||
/** checks and stores the local storage values */
|
||||
Success: boolean;
|
||||
/** Bulk Disbursement Transactions Data */
|
||||
bulkDisbursementTransactionsData = {};
|
||||
bulkDisbursementTransactionsData: {
|
||||
bulkRepaymentTransactions?: any[];
|
||||
bulkSavingsDueTransactions?: any[];
|
||||
} = {};
|
||||
/** Bulk Repayment Transactions Data */
|
||||
bulkRepaymentTransactions: any[] = [];
|
||||
/** Bulk Savings Due Data */
|
||||
@@ -261,7 +264,16 @@ export class IndividualCollectionSheetComponent implements OnInit {
|
||||
if (response.data) {
|
||||
if (type === 'loans') {
|
||||
const totalDue = this.getLoanTotalDueAmount(selectedData);
|
||||
const loanTransaction = {
|
||||
const loanTransaction: {
|
||||
loanId: any;
|
||||
transactionAmount: number;
|
||||
paymentTypeId?: string;
|
||||
accountNumber?: any;
|
||||
checkNumber?: number;
|
||||
routingCode?: string;
|
||||
receiptNumber?: number;
|
||||
bankNumber?: number;
|
||||
} = {
|
||||
loanId: selectedData.loanId,
|
||||
transactionAmount: totalDue
|
||||
};
|
||||
@@ -279,7 +291,17 @@ export class IndividualCollectionSheetComponent implements OnInit {
|
||||
if (isNaN(dueAmount)) {
|
||||
dueAmount = 0;
|
||||
}
|
||||
const savingsTransaction = {
|
||||
const savingsTransaction: {
|
||||
savingsId: any;
|
||||
transactionAmount: any;
|
||||
depositAccountType: number;
|
||||
accountNumber?: any;
|
||||
checkNumber?: number;
|
||||
routingCode?: string;
|
||||
receiptNumber?: number;
|
||||
bankNumber?: number;
|
||||
paymentTypeId?: string;
|
||||
} = {
|
||||
savingsId: selectedData.savingsId,
|
||||
transactionAmount: dueAmount,
|
||||
depositAccountType:
|
||||
|
||||
@@ -10,7 +10,7 @@ import { environment } from '../../../environments/environment';
|
||||
import { SettingsService } from 'app/settings/settings.service';
|
||||
|
||||
/** Http request (default) options headers. */
|
||||
const httpOptions = {
|
||||
const httpOptions: { headers: { [key: string]: string } } = {
|
||||
headers: {
|
||||
'Fineract-Platform-TenantId': environment.fineractPlatformTenantId
|
||||
}
|
||||
|
||||
@@ -107,7 +107,8 @@ export class HttpCacheService {
|
||||
*/
|
||||
setPersistence(persistence?: 'local' | 'session') {
|
||||
this.cleanCache();
|
||||
this.storage = persistence === 'local' || persistence === 'session' ? window[persistence + 'Storage'] : null;
|
||||
this.storage =
|
||||
persistence === 'local' ? window.localStorage : persistence === 'session' ? window.sessionStorage : null;
|
||||
this.loadCacheData();
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -41,6 +41,8 @@ export class FixedDepositsAccountActionsComponent {
|
||||
*/
|
||||
constructor(private route: ActivatedRoute) {
|
||||
const name = this.route.snapshot.params['name'];
|
||||
this.actions[name] = true;
|
||||
if (name && name in this.actions) {
|
||||
this.actions[name as keyof typeof this.actions] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+11
-4
@@ -5,6 +5,7 @@ import { SettingsService } from 'app/settings/settings.service';
|
||||
import { Dates } from 'app/core/utils/dates';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Currency, PaymentType } from 'app/shared/models/general.model';
|
||||
import { TransactionCommand, TransactionTypeFlags } from '../../../transaction.model';
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-fixed-deposits-cash-transaction',
|
||||
@@ -23,9 +24,9 @@ export class FixedDepositsCashTransactionComponent implements OnInit {
|
||||
/** Flag to enable payment details fields. */
|
||||
addPaymentDetailsFlag: Boolean = false;
|
||||
/** transaction type flag to render required UI */
|
||||
transactionType: { deposit: boolean; withdrawal: boolean } = { deposit: false, withdrawal: false };
|
||||
transactionType: TransactionTypeFlags = { deposit: false, withdrawal: false };
|
||||
/** transaction command for submit request */
|
||||
transactionCommand: string;
|
||||
transactionCommand: TransactionCommand;
|
||||
actionName: string;
|
||||
/** saving account's Id */
|
||||
accountId: string;
|
||||
@@ -53,8 +54,14 @@ export class FixedDepositsCashTransactionComponent implements OnInit {
|
||||
this.paymentTypeOptions = data.fixedDepositsAccountActionData.paymentTypeOptions;
|
||||
});
|
||||
this.actionName = this.route.snapshot.params['name'];
|
||||
this.transactionCommand = this.actionName.toLowerCase();
|
||||
this.transactionType[this.transactionCommand] = true;
|
||||
const lowerName = this.actionName.toLowerCase();
|
||||
if (lowerName === 'deposit' || lowerName === 'withdrawal') {
|
||||
this.transactionCommand = lowerName;
|
||||
this.transactionType[this.transactionCommand] = true;
|
||||
} else {
|
||||
throw new Error(`Invalid transaction action: ${this.actionName}`);
|
||||
}
|
||||
|
||||
this.accountId = this.route.parent.snapshot.params['fixedDepositAccountId'];
|
||||
}
|
||||
|
||||
|
||||
+11
-5
@@ -8,6 +8,7 @@ import { RecurringDepositsService } from '../../recurring-deposits.service';
|
||||
import { SettingsService } from 'app/settings/settings.service';
|
||||
import { Dates } from 'app/core/utils/dates';
|
||||
import { Currency } from 'app/shared/models/general.model';
|
||||
import { TransactionCommand, TransactionTypeFlags } from '../../../transaction.model';
|
||||
|
||||
/**
|
||||
* Deposits Recurring Deposits Account Component
|
||||
@@ -39,8 +40,8 @@ export class DepositRecurringDepositsAccountComponent implements OnInit {
|
||||
|
||||
action: string;
|
||||
actionName: string;
|
||||
transactionCommand: string;
|
||||
transactionType: { deposit: boolean; withdrawal: boolean } = { deposit: false, withdrawal: false };
|
||||
transactionCommand: TransactionCommand;
|
||||
transactionType: TransactionTypeFlags = { deposit: false, withdrawal: false };
|
||||
|
||||
/**
|
||||
* Retrieves action details transactions template data from `resolve`
|
||||
@@ -66,13 +67,18 @@ export class DepositRecurringDepositsAccountComponent implements OnInit {
|
||||
data.recurringDepositsAccountActionData.outstandingChargeAmount > 0
|
||||
) {
|
||||
this.outstandingChargeAmount = data.recurringDepositsAccountActionData.outstandingChargeAmount;
|
||||
this.transactionAmount = this.transactionAmount + this.outstandingChargeAmount;
|
||||
this.transactionAmount += this.outstandingChargeAmount;
|
||||
}
|
||||
});
|
||||
this.actionName = this.route.snapshot.params['name'];
|
||||
this.action = this.actionName.toLowerCase();
|
||||
this.transactionCommand = this.action.toLowerCase();
|
||||
this.transactionType[this.transactionCommand] = true;
|
||||
if (this.action === 'deposit' || this.action === 'withdrawal') {
|
||||
this.transactionCommand = this.action;
|
||||
this.transactionType[this.transactionCommand] = true;
|
||||
} else {
|
||||
throw new Error(`Invalid transaction action: ${this.actionName}`);
|
||||
}
|
||||
|
||||
this.accountId = this.route.parent.snapshot.params['recurringDepositAccountId'];
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -47,6 +47,8 @@ export class RecurringDepositsAccountActionsComponent {
|
||||
}
|
||||
});
|
||||
const name = this.route.snapshot.params['name'];
|
||||
this.actions[name] = true;
|
||||
if (name && name in this.actions) {
|
||||
this.actions[name as keyof typeof this.actions] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-2
@@ -69,8 +69,7 @@
|
||||
{{ 'labels.inputs.Note' | translate }}
|
||||
</div>
|
||||
|
||||
<div class="flex-50">
|
||||
*ngIf="transactionData.note">
|
||||
<div class="flex-50" *ngIf="transactionData.note">
|
||||
{{ transactionData.note }}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
export type TransactionCommand = 'deposit' | 'withdrawal';
|
||||
|
||||
export type TransactionTypeFlags = {
|
||||
[key in TransactionCommand]: boolean;
|
||||
};
|
||||
@@ -44,6 +44,8 @@ export class GroupActionsComponent {
|
||||
) {
|
||||
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
|
||||
const action = this.route.snapshot.params['action'];
|
||||
this.actions[action] = true;
|
||||
if (action && action in this.actions) {
|
||||
this.actions[action as keyof typeof this.actions] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -85,7 +85,7 @@ export class LoansAccountDatatableStepComponent implements OnInit {
|
||||
get payload(): any {
|
||||
const dateFormat = this.settingsService.dateFormat;
|
||||
const datatableDataValues = this.datatableForm.value;
|
||||
const data = {
|
||||
const data: { [key: string]: any } = {
|
||||
locale: this.settingsService.language.code
|
||||
};
|
||||
let existDate = false;
|
||||
|
||||
+7
-1
@@ -15,6 +15,12 @@ import { InputBase } from 'app/shared/form-dialog/formfield/model/input-base';
|
||||
import { Currency } from 'app/shared/models/general.model';
|
||||
import { CodeName, OptionData } from 'app/shared/models/option-data.model';
|
||||
|
||||
interface DisbursementData {
|
||||
id?: number;
|
||||
principal: number;
|
||||
expectedDisbursementDate: string | Date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Loans Account Terms Step
|
||||
*/
|
||||
@@ -62,7 +68,7 @@ export class LoansAccountTermsStepComponent implements OnInit, OnChanges {
|
||||
/** Client Active Loan Data */
|
||||
clientActiveLoanData: any;
|
||||
/** Multi Disbursement Data */
|
||||
disbursementDataSource: {}[] = [];
|
||||
disbursementDataSource: DisbursementData[] = [];
|
||||
/** Loan repayment strategies */
|
||||
transactionProcessingStrategyOptions: any = [];
|
||||
repaymentStrategyDisabled = false;
|
||||
|
||||
+3
-1
@@ -24,7 +24,9 @@ export class EditRepaymentScheduleComponent implements OnInit {
|
||||
/** Indicates If the Schedule has been validated */
|
||||
wasValidated = false;
|
||||
/** Stores the Repayment Schedule data */
|
||||
repaymentScheduleDetails: any[] | null = null;
|
||||
repaymentScheduleDetails: {
|
||||
periods: { period?: number; dueDate: string; totalDueForPeriod?: number; changed?: boolean }[];
|
||||
} | null = null;
|
||||
/** Stores the Installments changed */
|
||||
repaymentScheduleChanges: any = {};
|
||||
|
||||
|
||||
@@ -56,7 +56,12 @@ export class RescheduleLoanTabComponent {
|
||||
if (response.confirm) {
|
||||
const locale = this.settingsService.language.code;
|
||||
const dateFormat = this.settingsService.dateFormat;
|
||||
const payload = {
|
||||
const payload: {
|
||||
dateFormat: string;
|
||||
locale: string;
|
||||
approvedOnDate?: string;
|
||||
rejectedOnDate?: string;
|
||||
} = {
|
||||
dateFormat,
|
||||
locale
|
||||
};
|
||||
|
||||
@@ -386,7 +386,7 @@ export class TransactionsTabComponent implements OnInit {
|
||||
value: this.dateUtils.parseDate(transactionDate),
|
||||
type: 'datetime-local',
|
||||
required: true,
|
||||
minDate: transaction.date,
|
||||
minDate: this.dateUtils.parseDate(transaction.date),
|
||||
order: 1
|
||||
}),
|
||||
new InputBase({
|
||||
|
||||
+1
-2
@@ -43,8 +43,7 @@
|
||||
</mat-form-field>
|
||||
|
||||
<div class="flex-fill">
|
||||
<span class="expandcollapsebutton m-l-10 m-t-40 flex-75">
|
||||
(click)="addPaymentDetails()">
|
||||
<span class="expandcollapsebutton m-l-10 m-t-40 flex-75" (click)="addPaymentDetails()">
|
||||
<mat-slide-toggle>
|
||||
<div [className]="showPaymentDetails ? 'enabled' : 'disabled'">
|
||||
<span class="m-l-10">{{ 'labels.inputs.Show Payment Details' | translate }}</span>
|
||||
|
||||
@@ -25,9 +25,7 @@
|
||||
[routerLink]="[routeMap[row.objectType], row.objectId]"
|
||||
></tr>
|
||||
<tr *matNoDataRow>
|
||||
<td [attr.colspan]="displayedColumns.length" style="text-align: center; padding: 16px; color: #999">
|
||||
You don't have any notifications
|
||||
</td>
|
||||
<td [attr.colspan]="displayedColumns.length">You don't have any notifications</td>
|
||||
</tr>
|
||||
</table>
|
||||
<mat-paginator [pageSizeOptions]="[10, 25, 50, 100]" showFirstLastButtons></mat-paginator>
|
||||
|
||||
@@ -37,7 +37,7 @@ export class CreateHolidayComponent implements OnInit {
|
||||
// Stores office data in a trie-like structure
|
||||
officesTrie: any;
|
||||
// Stores office data for access from DOM via Office ID
|
||||
officesDict = {};
|
||||
officesDict: { [key: string]: any } = {};
|
||||
|
||||
// Angular Material Tree Configuration start ------------
|
||||
|
||||
@@ -100,7 +100,7 @@ export class CreateHolidayComponent implements OnInit {
|
||||
});
|
||||
}
|
||||
constructOfficeHierarchy() {
|
||||
const trie = {};
|
||||
const trie: Record<string, any> = {};
|
||||
// Iterates over all the offices
|
||||
this.officesData.forEach((office: any) => {
|
||||
this.officesDict[office.id] = office;
|
||||
@@ -114,7 +114,7 @@ export class CreateHolidayComponent implements OnInit {
|
||||
|
||||
// Temporary variable to store current object
|
||||
|
||||
let root = trie;
|
||||
let root: Record<string, any> = trie;
|
||||
|
||||
if (hierarchy.length === 0) {
|
||||
root[office.id] = {};
|
||||
|
||||
+1
-1
@@ -161,7 +161,7 @@ export class BusinessRuleParametersComponent implements OnInit, OnChanges {
|
||||
formattedResponse[newKey] = value;
|
||||
break;
|
||||
case 'select':
|
||||
formattedResponse[newKey] = value['id'];
|
||||
formattedResponse[newKey] = (value as { id: string | number })['id'];
|
||||
break;
|
||||
case 'date':
|
||||
const dateFormat = this.settingsService.dateFormat;
|
||||
|
||||
@@ -48,6 +48,6 @@ export class StatusLookupPipe implements PipeTransform {
|
||||
'smsCampaignStatus.closed': 'status-closed',
|
||||
'purchasedSharesStatusType.applied': 'status-pending'
|
||||
};
|
||||
return cssClassNameLookup[status];
|
||||
return cssClassNameLookup[status as keyof typeof cssClassNameLookup] ?? 'status-unknown';
|
||||
}
|
||||
}
|
||||
|
||||
+45
-10
@@ -91,7 +91,7 @@ export class FixedDepositProductInterestRateChartStepComponent implements OnInit
|
||||
this.clientClassificationData = this.fixedDepositProductsTemplate.chartTemplate.clientClassificationOptions;
|
||||
this.incentiveTypeData = this.fixedDepositProductsTemplate.chartTemplate.incentiveTypeOptions;
|
||||
|
||||
if (!(this.fixedDepositProductsTemplate === undefined)) {
|
||||
if (this.fixedDepositProductsTemplate) {
|
||||
this.assignFormData();
|
||||
}
|
||||
}
|
||||
@@ -145,7 +145,7 @@ export class FixedDepositProductInterestRateChartStepComponent implements OnInit
|
||||
formArray.push(chartSlabInfo);
|
||||
|
||||
// Iterate for every slab in chartSlab
|
||||
const chartIncentiveControl = chartDetailControl.controls['chartSlabs']['controls'][j];
|
||||
const chartIncentiveControl = (chartDetailControl.controls['chartSlabs'] as UntypedFormArray).controls[j];
|
||||
|
||||
// Iterate to input all the incentive for particular chart slab
|
||||
this.chartsDetail[i].chartSlabs[j].incentives.forEach((chartIncentiveDetail: any) => {
|
||||
@@ -158,8 +158,8 @@ export class FixedDepositProductInterestRateChartStepComponent implements OnInit
|
||||
chartIncentiveDetail.attributeName,
|
||||
Validators.required
|
||||
],
|
||||
attribureValue: [
|
||||
chartIncentiveDetail.attribureValue,
|
||||
attributeValue: [
|
||||
chartIncentiveDetail.attributeValue,
|
||||
Validators.required
|
||||
],
|
||||
conditionType: [
|
||||
@@ -175,7 +175,7 @@ export class FixedDepositProductInterestRateChartStepComponent implements OnInit
|
||||
Validators.required
|
||||
]
|
||||
});
|
||||
const newFormArray = chartIncentiveControl['controls']['incentives'] as UntypedFormArray;
|
||||
const newFormArray = (chartIncentiveControl as UntypedFormGroup).controls['incentives'] as UntypedFormArray;
|
||||
newFormArray.push(incentiveInfo);
|
||||
});
|
||||
});
|
||||
@@ -183,8 +183,8 @@ export class FixedDepositProductInterestRateChartStepComponent implements OnInit
|
||||
}
|
||||
|
||||
getChartsDetailsData() {
|
||||
this.chartDetailData.forEach((chartData: any) => {
|
||||
const chart = {
|
||||
this.chartDetailData.forEach((chartData: ChartData) => {
|
||||
const chart: Chart = {
|
||||
endDate: chartData.endDate ? new Date(chartData.endDate) : '',
|
||||
fromDate: chartData.fromDate ? new Date(chartData.fromDate) : '',
|
||||
isPrimaryGroupingByAmount: chartData.isPrimaryGroupingByAmount,
|
||||
@@ -193,7 +193,7 @@ export class FixedDepositProductInterestRateChartStepComponent implements OnInit
|
||||
chartSlabs: this.getChartSlabsData(chartData)
|
||||
};
|
||||
if (chartData.id) {
|
||||
chart['id'] = chartData.id;
|
||||
chart.id = chartData.id;
|
||||
}
|
||||
this.chartsDetail.push(chart);
|
||||
});
|
||||
@@ -213,7 +213,17 @@ export class FixedDepositProductInterestRateChartStepComponent implements OnInit
|
||||
}
|
||||
|
||||
chartSlabData.forEach((eachChartSlabData: any) => {
|
||||
const chartSlab = {
|
||||
const chartSlab: {
|
||||
id?: any;
|
||||
periodType: any;
|
||||
amountRangeFrom: any;
|
||||
amountRangeTo: any;
|
||||
annualInterestRate: any;
|
||||
description: any;
|
||||
fromPeriod: any;
|
||||
toPeriod: any;
|
||||
incentives: any[];
|
||||
} = {
|
||||
periodType: eachChartSlabData.periodType.id,
|
||||
amountRangeFrom: eachChartSlabData.amountRangeFrom,
|
||||
amountRangeTo: eachChartSlabData.amountRangeTo,
|
||||
@@ -221,7 +231,7 @@ export class FixedDepositProductInterestRateChartStepComponent implements OnInit
|
||||
description: eachChartSlabData.description ? eachChartSlabData.description : '',
|
||||
fromPeriod: eachChartSlabData.fromPeriod,
|
||||
toPeriod: eachChartSlabData.toPeriod,
|
||||
incentives: this.getIncentivesData(chartSlabData)
|
||||
incentives: this.getIncentivesData(eachChartSlabData)
|
||||
};
|
||||
if (eachChartSlabData.id) {
|
||||
chartSlab['id'] = eachChartSlabData.id;
|
||||
@@ -468,3 +478,28 @@ export class FixedDepositProductInterestRateChartStepComponent implements OnInit
|
||||
return fixedDepositProductInterestRateChart;
|
||||
}
|
||||
}
|
||||
|
||||
interface ChartData {
|
||||
id?: number;
|
||||
endDate?: string;
|
||||
fromDate?: string;
|
||||
isPrimaryGroupingByAmount: boolean;
|
||||
name: string;
|
||||
description: string;
|
||||
chartSlabs: ChartSlab[];
|
||||
}
|
||||
|
||||
interface ChartSlab {
|
||||
periodType?: string;
|
||||
fromPeriod?: number;
|
||||
toPeriod?: number;
|
||||
amountRangeFrom?: number;
|
||||
amountRangeTo?: number;
|
||||
annualInterestRate?: number;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
interface Chart extends Omit<ChartData, 'endDate' | 'fromDate'> {
|
||||
endDate: Date | string;
|
||||
fromDate: Date | string;
|
||||
}
|
||||
|
||||
+2
-2
@@ -378,7 +378,7 @@
|
||||
|
||||
<div class="flex-fill layout-row">
|
||||
<span class="flex-47">{{ 'labels.inputs.Repayment Strategy' | translate }}:</span>
|
||||
<span class="flex-53" class="repayment-strategy">{{
|
||||
<span class="flex-53 repayment-strategy">{{
|
||||
loanProduct.transactionProcessingStrategyName | translateKey: 'catalogs'
|
||||
}}</span>
|
||||
</div>
|
||||
@@ -563,7 +563,7 @@
|
||||
<span class="flex-53">{{ loanProduct.canUseForTopup | yesNo }}</span>
|
||||
</div>
|
||||
|
||||
<h3 class="mat-h3" class="flex-fill">{{ 'labels.heading.Interest Recalculation' | translate }}</h3>
|
||||
<h3 class="mat-h3 flex-fill">{{ 'labels.heading.Interest Recalculation' | translate }}</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
|
||||
+1
-1
@@ -212,7 +212,7 @@
|
||||
|
||||
<span class="flex-48 hide-lt-md"></span>
|
||||
|
||||
<div style="display: flex; justify-content: flex-start; width: 100%">
|
||||
<div class="full-width-flex">
|
||||
<div *ngIf="isAdvancedTransactionProcessingStrategy">
|
||||
<h3 class="mat-h4 flex-98">{{ 'labels.inputs.Loan Charge-off behaviour' | translate }}</h3>
|
||||
|
||||
|
||||
@@ -21,14 +21,12 @@
|
||||
<fa-icon
|
||||
(click)="arrowBooleansToggle(0); $event.stopPropagation()"
|
||||
*ngIf="!arrowBooleans[0]"
|
||||
style="z-index: 1000"
|
||||
icon="arrow-down"
|
||||
size="md"
|
||||
></fa-icon>
|
||||
<fa-icon
|
||||
(click)="arrowBooleansToggle(0); $event.stopPropagation()"
|
||||
*ngIf="arrowBooleans[0]"
|
||||
style="z-index: 1000"
|
||||
icon="arrow-up"
|
||||
size="md"
|
||||
></fa-icon>
|
||||
|
||||
+21
-4
@@ -145,7 +145,7 @@ export class RecurringDepositProductInterestRateChartStepComponent implements On
|
||||
formArray.push(chartSlabInfo);
|
||||
|
||||
// Iterate for every slab in chartSlab
|
||||
const chartIncentiveControl = chartDetailControl.controls['chartSlabs']['controls'][j];
|
||||
const chartIncentiveControl = (chartDetailControl.controls['chartSlabs'] as UntypedFormArray).controls[j];
|
||||
|
||||
// Iterate to input all the incentive for particular chart slab
|
||||
this.chartsDetail[i].chartSlabs[j].incentives.forEach((chartIncentiveDetail: any) => {
|
||||
@@ -175,7 +175,7 @@ export class RecurringDepositProductInterestRateChartStepComponent implements On
|
||||
Validators.required
|
||||
]
|
||||
});
|
||||
const newFormArray = chartIncentiveControl['controls']['incentives'] as UntypedFormArray;
|
||||
const newFormArray = (chartIncentiveControl as UntypedFormGroup).controls['incentives'] as UntypedFormArray;
|
||||
newFormArray.push(incentiveInfo);
|
||||
});
|
||||
});
|
||||
@@ -184,7 +184,14 @@ export class RecurringDepositProductInterestRateChartStepComponent implements On
|
||||
|
||||
getChartsDetailsData() {
|
||||
this.chartDetailData.forEach((chartData: any) => {
|
||||
const chart = {
|
||||
const chart: {
|
||||
id?: any;
|
||||
endDate: string | Date;
|
||||
fromDate: string | Date;
|
||||
isPrimaryGroupingByAmount: any;
|
||||
name: any;
|
||||
chartSlabs: any[];
|
||||
} = {
|
||||
endDate: chartData.endDate ? new Date(chartData.endDate) : '',
|
||||
fromDate: chartData.fromDate ? new Date(chartData.fromDate) : '',
|
||||
isPrimaryGroupingByAmount: chartData.isPrimaryGroupingByAmount,
|
||||
@@ -212,7 +219,17 @@ export class RecurringDepositProductInterestRateChartStepComponent implements On
|
||||
}
|
||||
|
||||
chartSlabData.forEach((eachChartSlabData: any) => {
|
||||
const chartSlab = {
|
||||
const chartSlab: {
|
||||
id?: any;
|
||||
periodType: any;
|
||||
amountRangeFrom: any;
|
||||
amountRangeTo: any;
|
||||
annualInterestRate: any;
|
||||
description: any;
|
||||
fromPeriod: any;
|
||||
toPeriod: any;
|
||||
incentives: any[];
|
||||
} = {
|
||||
periodType: eachChartSlabData.periodType.id,
|
||||
amountRangeFrom: eachChartSlabData.amountRangeFrom,
|
||||
amountRangeTo: eachChartSlabData.amountRangeTo,
|
||||
|
||||
@@ -13,7 +13,7 @@ import { SelectOption } from '../common-models/select-option.model';
|
||||
import { Dates } from 'app/core/utils/dates';
|
||||
import { GlobalConfiguration } from 'app/system/configurations/global-configurations-tab/configuration.model';
|
||||
|
||||
import * as XLSX from 'xlsx';
|
||||
import * as ExcelJS from 'exceljs';
|
||||
import { AlertService } from 'app/core/alert/alert.service';
|
||||
|
||||
/**
|
||||
@@ -251,7 +251,7 @@ export class RunReportComponent implements OnInit {
|
||||
formattedResponse[newKey] = value;
|
||||
break;
|
||||
case 'select':
|
||||
formattedResponse[newKey] = value['id'];
|
||||
formattedResponse[newKey] = (value as { id: string | number })['id'];
|
||||
break;
|
||||
case 'date':
|
||||
if (this.isTableReport()) {
|
||||
@@ -339,18 +339,46 @@ export class RunReportComponent implements OnInit {
|
||||
});
|
||||
}
|
||||
|
||||
exportToXLS(reportName: string, csvData: any, displayedColumns: string[]): void {
|
||||
async exportToXLS(reportName: string, csvData: any, displayedColumns: string[]): Promise<void> {
|
||||
const fileName = `${reportName}.xlsx`;
|
||||
|
||||
// Format data for ExcelJS
|
||||
const data = csvData.map((object: any) => {
|
||||
const row = {};
|
||||
const row: Record<string, any> = {};
|
||||
for (let i = 0; i < displayedColumns.length; i++) {
|
||||
row[displayedColumns[i]] = object.row[i];
|
||||
}
|
||||
return row;
|
||||
});
|
||||
const ws: XLSX.WorkSheet = XLSX.utils.json_to_sheet(data, { header: displayedColumns });
|
||||
const wb: XLSX.WorkBook = XLSX.utils.book_new();
|
||||
XLSX.utils.book_append_sheet(wb, ws, 'report');
|
||||
XLSX.writeFile(wb, fileName);
|
||||
|
||||
// Create workbook and worksheet
|
||||
const workbook = new ExcelJS.Workbook();
|
||||
const worksheet = workbook.addWorksheet('report');
|
||||
|
||||
// Add header
|
||||
worksheet.addRow(displayedColumns);
|
||||
|
||||
// Add data rows
|
||||
data.forEach((rowObj: any) => {
|
||||
worksheet.addRow(displayedColumns.map((col) => rowObj[col]));
|
||||
});
|
||||
|
||||
// Write to buffer and trigger download
|
||||
const buffer = await workbook.xlsx.writeBuffer();
|
||||
const blob = new Blob([buffer], {
|
||||
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
||||
});
|
||||
|
||||
// Native download logic (no FileSaver)
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = fileName;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(a);
|
||||
URL.revokeObjectURL(url);
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import { FormDialogComponent } from 'app/shared/form-dialog/form-dialog.componen
|
||||
import { environment } from 'environments/environment';
|
||||
import { ProgressBarService } from 'app/core/progress-bar/progress-bar.service';
|
||||
|
||||
import * as XLSX from 'xlsx';
|
||||
import * as ExcelJS from 'exceljs';
|
||||
|
||||
/**
|
||||
* Table and SMS Component
|
||||
@@ -143,16 +143,33 @@ export class TableAndSmsComponent implements OnChanges {
|
||||
exportToXLS(): void {
|
||||
const fileName = `${this.dataObject.report.name}.xlsx`;
|
||||
const data = this.csvData.map((object: any) => {
|
||||
const row = {};
|
||||
const row: { [key: string]: any } = {};
|
||||
for (let i = 0; i < this.displayedColumns.length; i++) {
|
||||
row[this.displayedColumns[i]] = object.row[i];
|
||||
}
|
||||
return row;
|
||||
});
|
||||
const ws: XLSX.WorkSheet = XLSX.utils.json_to_sheet(data, { header: this.displayedColumns });
|
||||
const wb: XLSX.WorkBook = XLSX.utils.book_new();
|
||||
XLSX.utils.book_append_sheet(wb, ws, 'Report');
|
||||
XLSX.writeFile(wb, fileName);
|
||||
|
||||
const workbook = new ExcelJS.Workbook();
|
||||
const worksheet = workbook.addWorksheet('Report');
|
||||
|
||||
// Add header row
|
||||
worksheet.addRow(this.displayedColumns);
|
||||
|
||||
// Add data rows
|
||||
data.forEach((rowObj: any) => {
|
||||
worksheet.addRow(this.displayedColumns.map((col) => rowObj[col]));
|
||||
});
|
||||
|
||||
workbook.xlsx.writeBuffer().then((buffer: any) => {
|
||||
const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = 'filename.xlsx';
|
||||
a.click();
|
||||
URL.revokeObjectURL(url);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+12
-8
@@ -7,6 +7,15 @@ import { SettingsService } from 'app/settings/settings.service';
|
||||
import { Currency } from 'app/shared/models/general.model';
|
||||
import { SystemService } from 'app/system/system.service';
|
||||
|
||||
type TransactionCommandType = 'holdamount' | 'blockaccount' | 'blockdeposit' | 'blockwithdrawal';
|
||||
|
||||
interface TransactionType {
|
||||
holdamount: boolean;
|
||||
blockaccount: boolean;
|
||||
blockdeposit: boolean;
|
||||
blockwithdrawal: boolean;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-manage-savings-account',
|
||||
templateUrl: './manage-savings-account.component.html',
|
||||
@@ -22,16 +31,11 @@ export class ManageSavingsAccountComponent implements OnInit {
|
||||
manageSavingsAccountForm: UntypedFormGroup;
|
||||
/** Savings Account Id */
|
||||
savingAccountId: string;
|
||||
transactionCommand: string;
|
||||
transactionCommand: TransactionCommandType;
|
||||
|
||||
reasonOptions: any = [];
|
||||
|
||||
transactionType: {
|
||||
holdamount: boolean;
|
||||
blockaccount: boolean;
|
||||
blockdeposit: boolean;
|
||||
blockwithdrawal: boolean;
|
||||
} = {
|
||||
transactionType: TransactionType = {
|
||||
holdamount: false,
|
||||
blockaccount: false,
|
||||
blockdeposit: false,
|
||||
@@ -130,7 +134,7 @@ export class ManageSavingsAccountComponent implements OnInit {
|
||||
|
||||
submit() {
|
||||
let command = '';
|
||||
let payload = {};
|
||||
let payload: { transactionAmount?: number; [key: string]: any } = {};
|
||||
|
||||
if (this.transactionType.holdamount) {
|
||||
const manageSavingsAccountFormData = this.manageSavingsAccountForm.value;
|
||||
|
||||
@@ -68,7 +68,9 @@ export class SavingAccountActionsComponent {
|
||||
this.currency = data.savingsAccountActionData.currency;
|
||||
}
|
||||
});
|
||||
const name = this.route.snapshot.params['name'];
|
||||
this.actions[name] = true;
|
||||
const name = this.route.snapshot.params['name'] as string;
|
||||
if (name in this.actions) {
|
||||
this.actions[name as keyof typeof this.actions] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -66,7 +66,7 @@ export class SavingsAccountTransactionsComponent implements OnInit {
|
||||
}
|
||||
});
|
||||
this.transactionCommand = this.route.snapshot.params['name'].toLowerCase();
|
||||
this.transactionType[this.transactionCommand] = true;
|
||||
this.transactionType[this.transactionCommand as 'deposit' | 'withdrawal'] = true;
|
||||
this.savingAccountId = this.route.snapshot.params['savingAccountId'];
|
||||
}
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ export class SavingsAccountViewComponent implements OnInit {
|
||||
taskPermissionName: 'CREATE_ACCOUNTTRANSFER'
|
||||
});
|
||||
}
|
||||
if (this.savingsAccountData.externalId && environment.interbankTransfers === 'true') {
|
||||
if (this.savingsAccountData.externalId && environment.interbankTransfers) {
|
||||
this.buttonConfig.addOption({
|
||||
name: 'Interbank Transfer',
|
||||
taskPermissionName: 'CREATE_ACCOUNTTRANSFER'
|
||||
|
||||
+1
-2
@@ -38,8 +38,7 @@
|
||||
</mat-form-field>
|
||||
|
||||
<div class="flex-fill">
|
||||
<span class="expandcollapsebutton m-l-10 m-t-40 flex-75">
|
||||
(click)="addPaymentDetails()">
|
||||
<span class="expandcollapsebutton m-l-10 m-t-40 flex-75" (click)="addPaymentDetails()">
|
||||
<mat-slide-toggle>
|
||||
<div [className]="showPaymentDetails ? 'enabled' : 'disabled'">
|
||||
<span class="m-l-10">{{ 'labels.inputs.Show Payment Details' | translate }}</span>
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
|
||||
/* eslint-disable @angular-eslint/component-selector */
|
||||
/* eslint-disable @angular-eslint/prefer-standalone */
|
||||
@Component({
|
||||
selector: 'ngx-mat-datetime-picker',
|
||||
template: `
|
||||
<mat-datepicker-toggle [for]="picker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #picker></mat-datepicker>
|
||||
`,
|
||||
standalone: false
|
||||
})
|
||||
export class DatetimePickerStubComponent {
|
||||
@Input() enableMeridian: boolean = true;
|
||||
}
|
||||
@@ -50,14 +50,12 @@
|
||||
<mat-label>{{ formfield.label }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
[ngxMatDatetimePicker]="datetimePicker"
|
||||
type="datetime-local"
|
||||
[min]="formfield.minDate"
|
||||
[max]="formfield.maxDate"
|
||||
[formControlName]="formfield.controlName"
|
||||
[required]="formfield.required"
|
||||
/>
|
||||
<mat-datepicker-toggle matSuffix [for]="datetimePicker"></mat-datepicker-toggle>
|
||||
<ngx-mat-datetime-picker #datetimePicker [enableMeridian]="true"></ngx-mat-datetime-picker>
|
||||
<mat-error *ngIf="form.controls[formfield.controlName].hasError('required')">
|
||||
{{ formfield.label }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
|
||||
@@ -1,13 +1,25 @@
|
||||
import { FormfieldBase } from './formfield-base';
|
||||
|
||||
interface DatepickerOptions {
|
||||
minDate?: Date;
|
||||
maxDate?: Date;
|
||||
controlType?: string;
|
||||
controlName?: string;
|
||||
label?: string;
|
||||
value?: any;
|
||||
required?: boolean;
|
||||
order?: number;
|
||||
type?: string;
|
||||
}
|
||||
|
||||
export class DatepickerBase extends FormfieldBase {
|
||||
controlType = 'datepicker';
|
||||
minDate: Date;
|
||||
maxDate: Date;
|
||||
|
||||
constructor(options: {} = {}) {
|
||||
constructor(options: DatepickerOptions = {}) {
|
||||
super(options);
|
||||
this.minDate = options['minDate'] || new Date(2000, 0, 1);
|
||||
this.maxDate = options['maxDate'] || new Date();
|
||||
this.minDate = options.minDate || new Date(2000, 0, 1);
|
||||
this.maxDate = options.maxDate || new Date();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,29 @@
|
||||
import { FormfieldBase } from './formfield-base';
|
||||
|
||||
// Define the base options interface based on FormfieldBase requirements
|
||||
interface FormfieldBaseOptions {
|
||||
controlType?: string;
|
||||
controlName?: string;
|
||||
label?: string;
|
||||
value?: any;
|
||||
required?: boolean;
|
||||
order?: number;
|
||||
}
|
||||
|
||||
// Extend the base options for DateTimePicker
|
||||
interface DateTimePickerOptions extends FormfieldBaseOptions {
|
||||
minDate?: Date;
|
||||
maxDate?: Date;
|
||||
}
|
||||
|
||||
export class DateTimepickerBase extends FormfieldBase {
|
||||
controlType = 'datetimepicker';
|
||||
minDate: Date;
|
||||
maxDate: Date;
|
||||
|
||||
constructor(options: {} = {}) {
|
||||
constructor(options: DateTimePickerOptions = {}) {
|
||||
super(options);
|
||||
this.minDate = options['minDate'] || new Date(2000, 0, 1);
|
||||
this.maxDate = options['maxDate'] || new Date();
|
||||
this.minDate = options.minDate || new Date(2000, 0, 1);
|
||||
this.maxDate = options.maxDate || new Date();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,25 @@
|
||||
import { FormfieldBase } from './formfield-base';
|
||||
|
||||
interface InputBaseOptions extends FormfieldBaseOptions {
|
||||
type?: string;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
interface FormfieldBaseOptions {
|
||||
controlType?: string;
|
||||
controlName?: string;
|
||||
label?: string;
|
||||
value?: any;
|
||||
required?: boolean;
|
||||
order?: number;
|
||||
}
|
||||
|
||||
export class InputBase extends FormfieldBase {
|
||||
controlType = 'input';
|
||||
type: string;
|
||||
|
||||
constructor(options: {} = {}) {
|
||||
constructor(options: InputBaseOptions = {}) {
|
||||
super(options);
|
||||
this.type = options['type'] || 'text';
|
||||
this.type = options.type || 'text';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,27 @@
|
||||
import { FormfieldBase } from './formfield-base';
|
||||
|
||||
interface SelectOption {
|
||||
label: string;
|
||||
value: string;
|
||||
data: {}[];
|
||||
}
|
||||
|
||||
interface SelectBaseOptions {
|
||||
options?: SelectOption;
|
||||
controlType?: string;
|
||||
controlName?: string;
|
||||
label?: string;
|
||||
value?: any;
|
||||
required?: boolean;
|
||||
order?: number;
|
||||
}
|
||||
|
||||
export class SelectBase extends FormfieldBase {
|
||||
controlType = 'select';
|
||||
options: {
|
||||
label: string;
|
||||
value: string;
|
||||
data: {}[];
|
||||
};
|
||||
options: SelectOption;
|
||||
|
||||
constructor(options: {} = {}) {
|
||||
constructor(options: SelectBaseOptions = {}) {
|
||||
super(options);
|
||||
this.options = options['options'];
|
||||
this.options = options.options || { label: '', value: '', data: [] };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ import { EntityDatatableTabComponent } from './tabs/entity-datatable-tab/entity-
|
||||
import { DatatableSingleRowComponent } from './tabs/entity-datatable-tab/datatable-single-row/datatable-single-row.component';
|
||||
import { DatatableMultiRowComponent } from './tabs/entity-datatable-tab/datatable-multi-row/datatable-multi-row.component';
|
||||
import { SvgIconComponent } from './svg-icon/svg-icon.component';
|
||||
import { NgxMatDatetimePickerModule, NgxMatNativeDateModule } from '@angular-material-components/datetime-picker';
|
||||
// import { NgxMatDatetimePickerModule, NgxMatNativeDateModule } from '@angular-material-components/datetime-picker';
|
||||
import { ViewJournalEntryComponent } from './accounting/view-journal-entry/view-journal-entry.component';
|
||||
import { ViewJournalEntryTransactionComponent } from './accounting/view-journal-entry-transaction/view-journal-entry-transaction.component';
|
||||
import { AccountNumberComponent } from './account-number/account-number.component';
|
||||
@@ -51,6 +51,7 @@ import { LongTextComponent } from './long-text/long-text.component';
|
||||
import { DropdownComponent } from './dropdown/dropdown.component';
|
||||
import { InputAmountComponent } from './input-amount/input-amount.component';
|
||||
import { InputPasswordComponent } from './input-password/input-password.component';
|
||||
import { DatetimePickerStubComponent } from './datetime-picker-stub/datetime-picker-stub.component'; // import Datetime Picker Stub
|
||||
|
||||
/**
|
||||
* Shared Module
|
||||
@@ -65,9 +66,9 @@ import { InputPasswordComponent } from './input-password/input-password.componen
|
||||
ReactiveFormsModule,
|
||||
TranslateModule,
|
||||
PipesModule,
|
||||
DirectivesModule,
|
||||
NgxMatDatetimePickerModule,
|
||||
NgxMatNativeDateModule
|
||||
DirectivesModule
|
||||
// NgxMatDatetimePickerModule,
|
||||
// NgxMatNativeDateModule
|
||||
],
|
||||
declarations: [
|
||||
FormfieldComponent,
|
||||
@@ -108,7 +109,9 @@ import { InputPasswordComponent } from './input-password/input-password.componen
|
||||
LongTextComponent,
|
||||
DropdownComponent,
|
||||
InputAmountComponent,
|
||||
InputPasswordComponent
|
||||
InputPasswordComponent,
|
||||
DatetimePickerStubComponent // temporarily added stub for datetime picker
|
||||
|
||||
],
|
||||
exports: [
|
||||
FileUploadComponent,
|
||||
@@ -143,7 +146,9 @@ import { InputPasswordComponent } from './input-password/input-password.componen
|
||||
ThemeToggleComponent,
|
||||
LongTextComponent,
|
||||
DropdownComponent,
|
||||
InputAmountComponent
|
||||
InputAmountComponent,
|
||||
DatetimePickerStubComponent // Export stub for datetime picker
|
||||
|
||||
]
|
||||
})
|
||||
export class SharedModule {}
|
||||
|
||||
@@ -44,6 +44,8 @@ export class SharesAccountActionsComponent {
|
||||
*/
|
||||
constructor(private route: ActivatedRoute) {
|
||||
const name = this.route.snapshot.params['name'];
|
||||
this.actions[name] = true;
|
||||
if (name && name in this.actions) {
|
||||
this.actions[name as keyof typeof this.actions] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+60
-36
@@ -8,31 +8,48 @@ import { PopoverService } from '../../configuration-wizard/popover/popover.servi
|
||||
import { ConfigurationWizardService } from '../../configuration-wizard/configuration-wizard.service';
|
||||
import { SystemService } from '../system.service';
|
||||
|
||||
interface Permission {
|
||||
code: string;
|
||||
id: number;
|
||||
selected: boolean;
|
||||
grouping?: string;
|
||||
}
|
||||
|
||||
interface PermissionGroup {
|
||||
permissions: Permission[];
|
||||
}
|
||||
|
||||
interface PermissionData {
|
||||
[key: string]: PermissionGroup;
|
||||
}
|
||||
|
||||
interface SubmitPermissionData {
|
||||
permissions: {
|
||||
[key: string]: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-configure-maker-checker-tasks',
|
||||
templateUrl: './configure-maker-checker-tasks.component.html',
|
||||
styleUrls: ['./configure-maker-checker-tasks.component.scss']
|
||||
})
|
||||
export class ConfigureMakerCheckerTasksComponent implements OnInit, AfterViewInit {
|
||||
permissionsData: any;
|
||||
permissionsData: Permission[] = [];
|
||||
groupings: string[] = [];
|
||||
currentGrouping = '';
|
||||
tempPermissionUIData: PermissionData = {};
|
||||
permissions: PermissionGroup = { permissions: [] };
|
||||
|
||||
formData = {};
|
||||
isDisabled = true;
|
||||
newEntry: any;
|
||||
selectedItem = '';
|
||||
previousGrouping = '';
|
||||
checkboxesChanged: Boolean = false;
|
||||
currentGrouping: string;
|
||||
formGroup: UntypedFormGroup;
|
||||
backupform: UntypedFormGroup;
|
||||
|
||||
permissions: {
|
||||
permissions: { code: string; id: number }[];
|
||||
};
|
||||
tempPermissionUIData: {
|
||||
permissions: { code: string }[];
|
||||
}[];
|
||||
|
||||
/* Reference of edit button */
|
||||
@ViewChild('buttonEdit') buttonEdit: ElementRef<any>;
|
||||
/* Template for popover on edit button */
|
||||
@@ -95,29 +112,33 @@ export class ConfigureMakerCheckerTasksComponent implements OnInit, AfterViewIni
|
||||
});
|
||||
}
|
||||
|
||||
setMakerCheckerTask() {
|
||||
this.tempPermissionUIData = [
|
||||
{
|
||||
permissions: []
|
||||
}
|
||||
];
|
||||
for (const i in this.permissionsData) {
|
||||
if (this.permissionsData[i]) {
|
||||
if (this.permissionsData[i].grouping !== this.currentGrouping) {
|
||||
this.currentGrouping = this.permissionsData[i].grouping;
|
||||
this.groupings.push(this.currentGrouping);
|
||||
this.tempPermissionUIData[this.currentGrouping] = { permissions: [] };
|
||||
}
|
||||
const temp = { code: this.permissionsData[i].code, id: i, selected: this.permissionsData[i].selected };
|
||||
this.tempPermissionUIData[this.currentGrouping].permissions.push(temp);
|
||||
setMakerCheckerTask(): void {
|
||||
this.tempPermissionUIData = {};
|
||||
|
||||
for (const permission of this.permissionsData) {
|
||||
if (permission.grouping !== this.currentGrouping) {
|
||||
this.currentGrouping = permission.grouping || '';
|
||||
this.groupings.push(this.currentGrouping);
|
||||
this.tempPermissionUIData[this.currentGrouping] = { permissions: [] };
|
||||
}
|
||||
|
||||
const temp: Permission = {
|
||||
code: permission.code,
|
||||
id: permission.id,
|
||||
selected: permission.selected
|
||||
};
|
||||
|
||||
this.tempPermissionUIData[this.currentGrouping].permissions.push(temp);
|
||||
}
|
||||
}
|
||||
|
||||
showPermissions(grouping: string) {
|
||||
this.permissions = this.tempPermissionUIData[grouping];
|
||||
this.selectedItem = grouping;
|
||||
this.previousGrouping = grouping;
|
||||
showPermissions(grouping: string): void {
|
||||
const group = this.tempPermissionUIData[grouping];
|
||||
if (group) {
|
||||
this.permissions = group;
|
||||
this.selectedItem = grouping;
|
||||
this.previousGrouping = grouping;
|
||||
}
|
||||
}
|
||||
|
||||
permissionName = function (name: any) {
|
||||
@@ -175,17 +196,20 @@ export class ConfigureMakerCheckerTasksComponent implements OnInit, AfterViewIni
|
||||
this.formGroup.controls.roster.disable();
|
||||
}
|
||||
|
||||
submit() {
|
||||
const value = this.formGroup.get('roster').value;
|
||||
const data = {};
|
||||
const permissionData = {
|
||||
submit(): void {
|
||||
const value = this.formGroup.get('roster')?.value;
|
||||
const permissionData: SubmitPermissionData = {
|
||||
permissions: {}
|
||||
};
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
data[value[i].code] = value[i].selected;
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
value.forEach((item) => {
|
||||
if (item.code && typeof item.selected === 'boolean') {
|
||||
permissionData.permissions[item.code] = item.selected;
|
||||
}
|
||||
});
|
||||
}
|
||||
permissionData.permissions = data;
|
||||
this.formGroup.controls.roster.disable();
|
||||
this.formGroup.get('roster')?.disable();
|
||||
this.checkboxesChanged = false;
|
||||
this.isDisabled = true;
|
||||
this.systemService.updateMakerCheckerPermission(permissionData).subscribe((response: any) => {});
|
||||
|
||||
@@ -108,7 +108,7 @@
|
||||
<br />
|
||||
|
||||
<div class="layout-row-wrap responsive-column">
|
||||
<p class="mat-title flex-20">{{ 'labels.inputs.Events' | translate }}<span style="color: red">*</span></p>
|
||||
<p class="mat-title flex-20">{{ 'labels.inputs.Events' | translate }}<span class="red">*</span></p>
|
||||
|
||||
<button mat-raised-button class="AddEventButton flex-20" type="button" color="primary" (click)="addEvent()">
|
||||
<fa-icon icon="plus" class="m-r-10"></fa-icon>
|
||||
|
||||
@@ -108,7 +108,7 @@
|
||||
<br />
|
||||
|
||||
<div class="layout-row-wrap responsive-column">
|
||||
<p class="mat-title flex-20">{{ 'labels.inputs.Events' | translate }} <span style="color: red">*</span></p>
|
||||
<p class="mat-title flex-20">{{ 'labels.inputs.Events' | translate }} <span class="red">*</span></p>
|
||||
|
||||
<button mat-raised-button class="AddEventButton flex-20" type="button" color="primary" (click)="addEvent()">
|
||||
<fa-icon icon="plus" class="m-r-10"></fa-icon>
|
||||
|
||||
@@ -9,7 +9,12 @@ import { FormDialogComponent } from 'app/shared/form-dialog/form-dialog.componen
|
||||
import { FormfieldBase } from 'app/shared/form-dialog/formfield/model/formfield-base';
|
||||
import { SelectBase } from 'app/shared/form-dialog/formfield/model/select-base';
|
||||
import { SystemService } from 'app/system/system.service';
|
||||
import { JobStep } from './workflow-diagram/workflow-diagram.component';
|
||||
|
||||
export interface JobStep {
|
||||
stepName: string;
|
||||
stepDescription: string;
|
||||
order: number;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-workflow-jobs',
|
||||
@@ -21,7 +26,7 @@ export class WorkflowJobsComponent implements OnInit {
|
||||
|
||||
jobNameOptions: any = [];
|
||||
jobStepsData: any = [];
|
||||
jobAvailableStepsData: any = [];
|
||||
jobAvailableStepsData: JobStep[] = [];
|
||||
jobStepsDataBase: any = [];
|
||||
jobStepName: String = null;
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-fill" ="48">
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-label>{{ 'labels.inputs.Text' | translate }}</mat-label>
|
||||
<input matInput maxlength="255" required formControlName="text" />
|
||||
<mat-error *ngIf="question.controls.text.hasError('required')">
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-fill" ="48">
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-label>{{ 'labels.inputs.Text' | translate }}</mat-label>
|
||||
<input matInput maxlength="255" required formControlName="text" />
|
||||
<mat-error *ngIf="question.get('text').hasError('required')">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/** Angular Imports */
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
|
||||
import { UntypedFormBuilder, UntypedFormGroup, Validators, FormArray } from '@angular/forms';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import * as _ from 'lodash';
|
||||
@@ -45,12 +45,14 @@ export class ViewRoleComponent implements OnInit {
|
||||
backupform: UntypedFormGroup;
|
||||
/** Temporarily stores Permission data */
|
||||
tempPermissionUIData: {
|
||||
permissions: { code: string }[];
|
||||
}[];
|
||||
[key: string]: {
|
||||
permissions: { code: string; id: number; selected?: boolean }[];
|
||||
};
|
||||
} = {};
|
||||
/** Stores permissions */
|
||||
permissions: {
|
||||
permissions: { code: string; id: number }[];
|
||||
};
|
||||
} = { permissions: [] };
|
||||
|
||||
/**
|
||||
* Retrieves the roledetails data from `resolve`.
|
||||
@@ -121,11 +123,7 @@ export class ViewRoleComponent implements OnInit {
|
||||
* Groups the permissions based on rules
|
||||
*/
|
||||
groupRules() {
|
||||
this.tempPermissionUIData = [
|
||||
{
|
||||
permissions: []
|
||||
}
|
||||
];
|
||||
this.tempPermissionUIData = {};
|
||||
for (const i in this.rolePermissionService.permissionUsageData) {
|
||||
if (this.rolePermissionService.permissionUsageData[i]) {
|
||||
if (this.rolePermissionService.permissionUsageData[i].grouping !== this.currentGrouping) {
|
||||
@@ -135,7 +133,7 @@ export class ViewRoleComponent implements OnInit {
|
||||
}
|
||||
const temp = {
|
||||
code: this.rolePermissionService.permissionUsageData[i].code,
|
||||
id: i,
|
||||
id: +i,
|
||||
selected: this.rolePermissionService.permissionUsageData[i].selected
|
||||
};
|
||||
this.tempPermissionUIData[this.currentGrouping].permissions.push(temp);
|
||||
@@ -177,7 +175,7 @@ export class ViewRoleComponent implements OnInit {
|
||||
name = name || '';
|
||||
// replace '_' with ' '
|
||||
name = name.replace(/_/g, ' ');
|
||||
// for reorts replace read with view
|
||||
// for reports replace read with view
|
||||
if (this.previousGrouping === 'report') {
|
||||
name = name.replace(/READ/g, 'View');
|
||||
}
|
||||
@@ -185,7 +183,7 @@ export class ViewRoleComponent implements OnInit {
|
||||
}
|
||||
|
||||
/**
|
||||
* Backups the valued
|
||||
* Backups the values
|
||||
*/
|
||||
backupCheckValues() {
|
||||
this.backupform = _.cloneDeep(this.formGroup) as UntypedFormGroup;
|
||||
@@ -220,7 +218,7 @@ export class ViewRoleComponent implements OnInit {
|
||||
*/
|
||||
submit() {
|
||||
const value = this.formGroup.get('roster').value;
|
||||
const data = {};
|
||||
const data: { [key: string]: boolean } = {};
|
||||
const permissionData = {
|
||||
permissions: {}
|
||||
};
|
||||
@@ -238,8 +236,9 @@ export class ViewRoleComponent implements OnInit {
|
||||
* Selects all the permission of a particular role
|
||||
*/
|
||||
selectAll() {
|
||||
const roster = this.formGroup.get('roster') as FormArray;
|
||||
for (let i = 0; i < this.permissions.permissions.length; i++) {
|
||||
this.formGroup.controls.roster['controls'][this.permissions.permissions[i].id].patchValue({
|
||||
roster.at(this.permissions.permissions[i].id).patchValue({
|
||||
selected: true
|
||||
});
|
||||
}
|
||||
@@ -249,8 +248,9 @@ export class ViewRoleComponent implements OnInit {
|
||||
* Deselects all the permissions of a particular role
|
||||
*/
|
||||
deselectAll() {
|
||||
const roster = this.formGroup.get('roster') as FormArray;
|
||||
for (let i = 0; i < this.permissions.permissions.length; i++) {
|
||||
this.formGroup.controls.roster['controls'][this.permissions.permissions[i].id].patchValue({
|
||||
roster.at(this.permissions.permissions[i].id).patchValue({
|
||||
selected: false
|
||||
});
|
||||
}
|
||||
|
||||
+14
-8
@@ -15,6 +15,12 @@ import { SettingsService } from 'app/settings/settings.service';
|
||||
import { Dates } from 'app/core/utils/dates';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
interface OfficeNode {
|
||||
id: number;
|
||||
name: string;
|
||||
loans: any[];
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-loan-approval',
|
||||
templateUrl: './loan-approval.component.html',
|
||||
@@ -32,7 +38,7 @@ export class LoanApprovalComponent {
|
||||
/** Row Selection Data */
|
||||
selection: SelectionModel<any>;
|
||||
/** Map data */
|
||||
idToNodeMap = {};
|
||||
idToNodeMap: { [key: number]: OfficeNode } = {};
|
||||
/** Grouped Office Data */
|
||||
officesArray: any[];
|
||||
/** List of Requests */
|
||||
@@ -79,15 +85,15 @@ export class LoanApprovalComponent {
|
||||
});
|
||||
this.loans.forEach((loanEle: any) => {
|
||||
if (loanEle.status.pendingApproval) {
|
||||
let tempOffice = {};
|
||||
let tempOffice: OfficeNode | undefined;
|
||||
if (loanEle.clientOfficeId) {
|
||||
tempOffice = this.idToNodeMap[loanEle.clientOfficeId];
|
||||
tempOffice['loans'].push(loanEle);
|
||||
} else {
|
||||
if (loanEle.group) {
|
||||
tempOffice = this.idToNodeMap[loanEle.group.officeId];
|
||||
tempOffice['loans'].push(loanEle);
|
||||
}
|
||||
} else if (loanEle.group?.officeId) {
|
||||
tempOffice = this.idToNodeMap[loanEle.group.officeId];
|
||||
}
|
||||
|
||||
if (tempOffice) {
|
||||
tempOffice.loans.push(loanEle);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
+10
-3
@@ -15,6 +15,13 @@ import { SettingsService } from 'app/settings/settings.service';
|
||||
import { Dates } from 'app/core/utils/dates';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
interface RescheduleFormData {
|
||||
dateFormat: string;
|
||||
locale: string;
|
||||
approvedOnDate?: string;
|
||||
rejectedOnDate?: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-reschedule-loan',
|
||||
templateUrl: './reschedule-loan.component.html',
|
||||
@@ -107,14 +114,14 @@ export class RescheduleLoanComponent {
|
||||
const dateFormat = this.settingsService.dateFormat;
|
||||
const transactionDate = this.dateUtils.formatDate(this.settingsService.businessDate, dateFormat);
|
||||
const locale = this.settingsService.language.code;
|
||||
const formData = {
|
||||
const formData: RescheduleFormData = {
|
||||
dateFormat,
|
||||
locale
|
||||
};
|
||||
if (command === 'approve') {
|
||||
formData['approvedOnDate'] = transactionDate;
|
||||
formData.approvedOnDate = transactionDate;
|
||||
} else {
|
||||
formData['rejectedOnDate'] = transactionDate;
|
||||
formData.rejectedOnDate = transactionDate;
|
||||
}
|
||||
const listSelectedAccounts = this.selection.selected;
|
||||
this.batchRequests = [];
|
||||
|
||||
Reference in New Issue
Block a user