DDS: Agent settlement (Agent Tran), Close Party account UI, reports UI, Party-Savings link field
This commit is contained in:
@@ -0,0 +1,355 @@
|
||||
<!--
|
||||
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/.
|
||||
-->
|
||||
|
||||
<div class="am-container">
|
||||
<div class="am-header">
|
||||
<button mat-stroked-button [routerLink]="['../']" class="am-back">
|
||||
<i class="fas fa-arrow-left"></i> {{ 'labels.heading.Organization' | translate }}
|
||||
</button>
|
||||
<h2 class="am-header__title">Agent Master Entry</h2>
|
||||
</div>
|
||||
|
||||
<div class="am-card">
|
||||
<form [formGroup]="agentForm">
|
||||
<div class="am-section">
|
||||
<div class="am-section__header">
|
||||
<i class="fas fa-id-card"></i>
|
||||
<h3>Agent Details</h3>
|
||||
</div>
|
||||
<div class="am-grid">
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>Client ID</mat-label>
|
||||
<input matInput required formControlName="clientId" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>Agent Code</mat-label>
|
||||
<input matInput formControlName="agentCode" placeholder="Auto-generated" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="am-field am-field--wide">
|
||||
<mat-label>Agent Name ID</mat-label>
|
||||
<input matInput required formControlName="agentNameId" placeholder="Person or institution name" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="am-field am-field--wide">
|
||||
<mat-label>Agent Address (Line 1)</mat-label>
|
||||
<input matInput required formControlName="agentAddress1" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="am-field am-field--wide">
|
||||
<mat-label>Agent Address (Line 2)</mat-label>
|
||||
<input matInput formControlName="agentAddress2" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>Agent City</mat-label>
|
||||
<input matInput required formControlName="agentCity" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>Agent PinCode</mat-label>
|
||||
<input matInput required formControlName="agentPinCode" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>Agent Telephone</mat-label>
|
||||
<input matInput formControlName="agentTelephone" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>Home Branch</mat-label>
|
||||
<input matInput required formControlName="homeBranch" />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="am-section">
|
||||
<div class="am-section__header">
|
||||
<i class="fas fa-percent"></i>
|
||||
<h3>Collection & Commission Settings</h3>
|
||||
</div>
|
||||
<div class="am-grid">
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>Com. Calculation</mat-label>
|
||||
<mat-select required formControlName="commissionCalculation">
|
||||
<mat-option value="Yes">Yes</mat-option>
|
||||
<mat-option value="No">No</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>TDS</mat-label>
|
||||
<mat-select required formControlName="tdsApplicable">
|
||||
<mat-option value="Yes">Yes</mat-option>
|
||||
<mat-option value="No">No</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>TDS %</mat-label>
|
||||
<input matInput type="number" formControlName="tdsPercent" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>Cur.TDS</mat-label>
|
||||
<input matInput formControlName="currentTds" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>TDS Amt</mat-label>
|
||||
<input matInput formControlName="tdsAmount" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>Limit</mat-label>
|
||||
<input matInput type="number" formControlName="limit" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>Machine Rent</mat-label>
|
||||
<input matInput type="number" formControlName="machineRent" />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="am-section">
|
||||
<div class="am-section__header">
|
||||
<i class="fas fa-piggy-bank"></i>
|
||||
<h3>Settlement & Security Accounts</h3>
|
||||
</div>
|
||||
<div class="am-grid">
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>Saving Branch</mat-label>
|
||||
<input matInput required formControlName="savingBranch" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>Agent Saving A/C Type</mat-label>
|
||||
<mat-select required formControlName="agentSavingAccountType">
|
||||
@for (accountType of agentSavingAccountTypes; track accountType) {
|
||||
<mat-option [value]="accountType">{{ accountType }}</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>Agent Saving A/C No</mat-label>
|
||||
<input matInput required formControlName="agentSavingAccountNo" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>Trf Branch</mat-label>
|
||||
<input matInput formControlName="transferBranch" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>Trf.Amt A/C Type</mat-label>
|
||||
<input matInput formControlName="transferAmountAccountType" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>Trf.Amt A/C No</mat-label>
|
||||
<input matInput formControlName="transferAccountNo" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>Agent Security Branch</mat-label>
|
||||
<input matInput formControlName="agentSecurityBranch" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>Agent Security A/C Type</mat-label>
|
||||
<mat-select formControlName="agentSecurityAccountType">
|
||||
@for (accountType of agentSavingAccountTypes; track accountType) {
|
||||
<mat-option [value]="accountType">{{ accountType }}</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>Agent Security A/C No</mat-label>
|
||||
<input matInput formControlName="agentSecurityAccountNo" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>Agent Opening Date</mat-label>
|
||||
<input matInput required [matDatepicker]="openingDatePicker" formControlName="agentOpeningDate" />
|
||||
<mat-datepicker-toggle matIconSuffix [for]="openingDatePicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #openingDatePicker></mat-datepicker>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>Agent Birth Date</mat-label>
|
||||
<input
|
||||
matInput
|
||||
required
|
||||
[max]="maxDate"
|
||||
[matDatepicker]="birthDatePicker"
|
||||
formControlName="agentBirthDate"
|
||||
/>
|
||||
<mat-datepicker-toggle matIconSuffix [for]="birthDatePicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #birthDatePicker></mat-datepicker>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>Agent Current Balance</mat-label>
|
||||
<input matInput formControlName="agentCurrentBalance" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>Agent Opening Balance</mat-label>
|
||||
<input matInput formControlName="agentOpeningBalance" />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="am-section">
|
||||
<div class="am-section__header">
|
||||
<i class="fas fa-clock"></i>
|
||||
<h3>Collection Limit History</h3>
|
||||
<button mat-stroked-button type="button" class="am-add-guarantor" (click)="addLimit()">
|
||||
<i class="fas fa-plus"></i> Add Limit
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@if (limits.length === 0) {
|
||||
<p class="am-empty-guarantors">No limit periods added yet.</p>
|
||||
}
|
||||
|
||||
@for (limitRow of limits.controls; track limitRow; let i = $index) {
|
||||
<div class="am-limit-row" [formGroup]="$any(limitRow)">
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>From Date</mat-label>
|
||||
<input matInput required [matDatepicker]="fromPicker" formControlName="fromDate" />
|
||||
<mat-datepicker-toggle matIconSuffix [for]="fromPicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #fromPicker></mat-datepicker>
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>To Date</mat-label>
|
||||
<input matInput required [matDatepicker]="toPicker" formControlName="toDate" />
|
||||
<mat-datepicker-toggle matIconSuffix [for]="toPicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #toPicker></mat-datepicker>
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>Limit</mat-label>
|
||||
<input matInput required type="number" formControlName="limit" />
|
||||
</mat-form-field>
|
||||
<button
|
||||
mat-icon-button
|
||||
type="button"
|
||||
class="am-remove-guarantor"
|
||||
(click)="removeLimit(i)"
|
||||
matTooltip="Remove limit period"
|
||||
>
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="am-section">
|
||||
<div class="am-section__header">
|
||||
<i class="fas fa-user-shield"></i>
|
||||
<h3>Guarantor's Detail</h3>
|
||||
<button mat-stroked-button type="button" class="am-add-guarantor" (click)="addGuarantor()">
|
||||
<i class="fas fa-plus"></i> Add Guarantor
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@if (guarantors.length === 0) {
|
||||
<p class="am-empty-guarantors">No guarantors added yet.</p>
|
||||
}
|
||||
|
||||
@for (guarantor of guarantors.controls; track guarantor; let i = $index) {
|
||||
<div class="am-guarantor-row" [formGroup]="$any(guarantor)">
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>Client ID</mat-label>
|
||||
<input matInput required formControlName="clientId" />
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>Guarantor Name</mat-label>
|
||||
<input matInput required formControlName="guarantorName" />
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>Address 1</mat-label>
|
||||
<input matInput required formControlName="address1" />
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>Address 2</mat-label>
|
||||
<input matInput formControlName="address2" />
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>City</mat-label>
|
||||
<input matInput required formControlName="city" />
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>Pin Code</mat-label>
|
||||
<input matInput required formControlName="pinCode" />
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>Telephone</mat-label>
|
||||
<input matInput formControlName="telephone" />
|
||||
</mat-form-field>
|
||||
<button
|
||||
mat-icon-button
|
||||
type="button"
|
||||
class="am-remove-guarantor"
|
||||
(click)="removeGuarantor(i)"
|
||||
matTooltip="Remove guarantor"
|
||||
>
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="am-section">
|
||||
<div class="am-section__header">
|
||||
<i class="fas fa-wallet"></i>
|
||||
<h3>Deductions & Deposits</h3>
|
||||
</div>
|
||||
<div class="am-grid">
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>Comm</mat-label>
|
||||
<input matInput formControlName="commission" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>Other Comm</mat-label>
|
||||
<input matInput type="number" formControlName="otherCommission" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>Ag.Deposit</mat-label>
|
||||
<input matInput type="number" formControlName="agentDeposit" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>Adv.Festival</mat-label>
|
||||
<input matInput type="number" formControlName="festivalAdvance" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="am-field">
|
||||
<mat-label>Other Deduction</mat-label>
|
||||
<input matInput type="number" formControlName="otherDeduction" />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="am-action-bar">
|
||||
<button mat-raised-button type="button" (click)="exit()">Exit</button>
|
||||
<button mat-stroked-button type="button" (click)="cancel()">Cancel</button>
|
||||
<button mat-stroked-button type="button" (click)="retrieve()">Retrieve</button>
|
||||
<button mat-raised-button color="primary" type="button" [disabled]="agentForm.invalid" (click)="save()">
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,141 @@
|
||||
/**
|
||||
* 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/.
|
||||
*/
|
||||
|
||||
$primary: #0f766e;
|
||||
|
||||
.am-container {
|
||||
max-width: 1040px;
|
||||
margin: 0 auto;
|
||||
padding: 24px 16px;
|
||||
}
|
||||
|
||||
.am-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
&__title {
|
||||
margin: 0;
|
||||
font-size: 22px;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.am-back {
|
||||
color: $primary;
|
||||
}
|
||||
|
||||
.am-card {
|
||||
background: var(--md-sys-color-surface, #fff);
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 8px rgb(0 0 0 / 8%);
|
||||
padding: 8px 24px 24px;
|
||||
}
|
||||
|
||||
.am-section {
|
||||
padding: 20px 0;
|
||||
border-bottom: 1px solid rgb(0 0 0 / 8%);
|
||||
|
||||
&:last-of-type {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
&__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
margin-bottom: 16px;
|
||||
|
||||
i {
|
||||
color: $primary;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.am-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 8px 16px;
|
||||
}
|
||||
|
||||
.am-field {
|
||||
width: 100%;
|
||||
|
||||
&--wide {
|
||||
grid-column: span 2;
|
||||
}
|
||||
}
|
||||
|
||||
.am-add-guarantor {
|
||||
color: $primary;
|
||||
}
|
||||
|
||||
.am-empty-guarantors {
|
||||
color: rgb(0 0 0 / 50%);
|
||||
font-size: 14px;
|
||||
margin: 0 0 8px;
|
||||
}
|
||||
|
||||
.am-guarantor-row {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(7, 1fr) auto;
|
||||
gap: 8px 12px;
|
||||
align-items: start;
|
||||
padding: 10px 0;
|
||||
border-top: 1px dashed rgb(0 0 0 / 10%);
|
||||
|
||||
&:first-of-type {
|
||||
border-top: none;
|
||||
}
|
||||
}
|
||||
|
||||
.am-limit-row {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr) auto;
|
||||
gap: 8px 12px;
|
||||
align-items: start;
|
||||
padding: 10px 0;
|
||||
border-top: 1px dashed rgb(0 0 0 / 10%);
|
||||
|
||||
&:first-of-type {
|
||||
border-top: none;
|
||||
}
|
||||
}
|
||||
|
||||
.am-remove-guarantor {
|
||||
color: #b91c1c;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.am-action-bar {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 12px;
|
||||
margin-top: 20px;
|
||||
padding-top: 16px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
@media (width <= 900px) {
|
||||
.am-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
.am-guarantor-row,
|
||||
.am-limit-row {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,381 @@
|
||||
/**
|
||||
* 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/.
|
||||
*/
|
||||
|
||||
/** Angular Imports */
|
||||
import { Component, inject } from '@angular/core';
|
||||
import { UntypedFormBuilder, UntypedFormGroup, UntypedFormArray, Validators } from '@angular/forms';
|
||||
import { Router } from '@angular/router';
|
||||
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
||||
|
||||
/** Custom Services */
|
||||
import { OrganizationService } from 'app/organization/organization.service';
|
||||
import { SettingsService } from 'app/settings/settings.service';
|
||||
import { Dates } from 'app/core/utils/dates';
|
||||
|
||||
/**
|
||||
* Agent Master Entry component.
|
||||
*
|
||||
* A DDS collection agent — either a person or an institution — registered
|
||||
* with its own settlement savings account and one or more guarantors. As of
|
||||
* 2026-08-24 the Agent also does the daily collection work directly (the
|
||||
* SubAgent tier was removed): it carries the collection-limit history,
|
||||
* TDS/commission settings and security account SubAgent used to own.
|
||||
*
|
||||
* Backed by its own DDS Agent API (`/dds/agents`) - independent of Staff/
|
||||
* Client CRUD, per the DDS agent/commission hierarchy being genuinely new
|
||||
* feature work.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'mifosx-agent-master',
|
||||
templateUrl: './agent-master.component.html',
|
||||
styleUrls: ['./agent-master.component.scss'],
|
||||
imports: [...STANDALONE_SHARED_IMPORTS]
|
||||
})
|
||||
export class AgentMasterComponent {
|
||||
private formBuilder = inject(UntypedFormBuilder);
|
||||
private router = inject(Router);
|
||||
private organizationService = inject(OrganizationService);
|
||||
private settingsService = inject(SettingsService);
|
||||
private dateUtils = inject(Dates);
|
||||
|
||||
maxDate = new Date();
|
||||
agentId: number | null = null;
|
||||
|
||||
agentSavingAccountTypes = [
|
||||
'Savings Deposit Individual A/C',
|
||||
'Savings Deposit Joint A/C',
|
||||
'Current Account'
|
||||
];
|
||||
|
||||
agentForm: UntypedFormGroup = this.formBuilder.group({
|
||||
clientId: [
|
||||
'',
|
||||
Validators.required
|
||||
],
|
||||
agentCode: [
|
||||
{
|
||||
value: '',
|
||||
disabled: true
|
||||
}
|
||||
],
|
||||
agentNameId: [
|
||||
'',
|
||||
Validators.required
|
||||
],
|
||||
agentAddress1: [
|
||||
'',
|
||||
Validators.required
|
||||
],
|
||||
agentAddress2: [''],
|
||||
agentCity: [
|
||||
'',
|
||||
Validators.required
|
||||
],
|
||||
agentPinCode: [
|
||||
'',
|
||||
Validators.required
|
||||
],
|
||||
agentTelephone: [''],
|
||||
agentSavingAccountType: [
|
||||
'',
|
||||
Validators.required
|
||||
],
|
||||
agentSavingAccountNo: [
|
||||
'',
|
||||
Validators.required
|
||||
],
|
||||
agentOpeningDate: [
|
||||
'',
|
||||
Validators.required
|
||||
],
|
||||
agentBirthDate: [
|
||||
'',
|
||||
Validators.required
|
||||
],
|
||||
agentCurrentBalance: [
|
||||
{
|
||||
value: 0,
|
||||
disabled: true
|
||||
}
|
||||
],
|
||||
agentOpeningBalance: [
|
||||
{
|
||||
value: 0,
|
||||
disabled: true
|
||||
}
|
||||
],
|
||||
homeBranch: [
|
||||
'',
|
||||
Validators.required
|
||||
],
|
||||
tdsApplicable: [
|
||||
'No',
|
||||
Validators.required
|
||||
],
|
||||
tdsPercent: [0],
|
||||
currentTds: [
|
||||
{
|
||||
value: 0,
|
||||
disabled: true
|
||||
}
|
||||
],
|
||||
tdsAmount: [
|
||||
{
|
||||
value: 0,
|
||||
disabled: true
|
||||
}
|
||||
],
|
||||
savingBranch: [
|
||||
'',
|
||||
Validators.required
|
||||
],
|
||||
transferBranch: [''],
|
||||
transferAmountAccountType: [''],
|
||||
transferAccountNo: [''],
|
||||
commissionCalculation: [
|
||||
'Yes',
|
||||
Validators.required
|
||||
],
|
||||
limit: [0],
|
||||
machineRent: [0],
|
||||
agentSecurityBranch: [''],
|
||||
agentSecurityAccountType: [''],
|
||||
agentSecurityAccountNo: [''],
|
||||
commission: [
|
||||
{
|
||||
value: 0,
|
||||
disabled: true
|
||||
}
|
||||
],
|
||||
otherCommission: [0],
|
||||
agentDeposit: [0],
|
||||
festivalAdvance: [0],
|
||||
otherDeduction: [0],
|
||||
limits: this.formBuilder.array([]),
|
||||
guarantors: this.formBuilder.array([])
|
||||
});
|
||||
|
||||
get limits(): UntypedFormArray {
|
||||
return this.agentForm.get('limits') as UntypedFormArray;
|
||||
}
|
||||
|
||||
get guarantors(): UntypedFormArray {
|
||||
return this.agentForm.get('guarantors') as UntypedFormArray;
|
||||
}
|
||||
|
||||
private buildLimitGroup(): UntypedFormGroup {
|
||||
return this.formBuilder.group({
|
||||
fromDate: [
|
||||
'',
|
||||
Validators.required
|
||||
],
|
||||
toDate: [
|
||||
'',
|
||||
Validators.required
|
||||
],
|
||||
limit: [
|
||||
0,
|
||||
Validators.required
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
private buildGuarantorGroup(): UntypedFormGroup {
|
||||
return this.formBuilder.group({
|
||||
clientId: [
|
||||
'',
|
||||
Validators.required
|
||||
],
|
||||
guarantorName: [
|
||||
'',
|
||||
Validators.required
|
||||
],
|
||||
address1: [
|
||||
'',
|
||||
Validators.required
|
||||
],
|
||||
address2: [''],
|
||||
city: [
|
||||
'',
|
||||
Validators.required
|
||||
],
|
||||
pinCode: [
|
||||
'',
|
||||
Validators.required
|
||||
],
|
||||
telephone: ['']
|
||||
});
|
||||
}
|
||||
|
||||
addLimit(): void {
|
||||
this.limits.push(this.buildLimitGroup());
|
||||
}
|
||||
|
||||
removeLimit(index: number): void {
|
||||
this.limits.removeAt(index);
|
||||
}
|
||||
|
||||
addGuarantor(): void {
|
||||
this.guarantors.push(this.buildGuarantorGroup());
|
||||
}
|
||||
|
||||
removeGuarantor(index: number): void {
|
||||
this.guarantors.removeAt(index);
|
||||
}
|
||||
|
||||
retrieve(): void {
|
||||
const clientId = this.agentForm.get('clientId')?.value;
|
||||
if (!clientId) {
|
||||
return;
|
||||
}
|
||||
this.organizationService.getAgents().subscribe((agents: any[]) => {
|
||||
const match = (agents || []).find((agent) => String(agent.clientId) === String(clientId));
|
||||
if (match) {
|
||||
this.patchFormFromAgent(match);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
cancel(): void {
|
||||
this.agentId = null;
|
||||
this.agentForm.reset();
|
||||
this.agentForm.patchValue({
|
||||
agentCurrentBalance: 0,
|
||||
agentOpeningBalance: 0,
|
||||
tdsApplicable: 'No',
|
||||
commissionCalculation: 'Yes',
|
||||
currentTds: 0,
|
||||
tdsAmount: 0,
|
||||
commission: 0
|
||||
});
|
||||
this.limits.clear();
|
||||
this.guarantors.clear();
|
||||
}
|
||||
|
||||
exit(): void {
|
||||
this.router.navigate(['/organization']);
|
||||
}
|
||||
|
||||
save(): void {
|
||||
const raw = this.agentForm.getRawValue();
|
||||
const dateFormat = this.settingsService.dateFormat;
|
||||
const locale = this.settingsService.language.code;
|
||||
|
||||
const payload: any = {
|
||||
clientId: Number(raw.clientId),
|
||||
agentNameId: raw.agentNameId,
|
||||
agentAddress1: raw.agentAddress1,
|
||||
agentAddress2: raw.agentAddress2 || undefined,
|
||||
agentCity: raw.agentCity,
|
||||
agentPinCode: raw.agentPinCode,
|
||||
agentTelephone: raw.agentTelephone || undefined,
|
||||
agentSavingAccountType: raw.agentSavingAccountType,
|
||||
agentSavingAccountNo: raw.agentSavingAccountNo,
|
||||
agentOpeningDate: this.dateUtils.formatDate(raw.agentOpeningDate, dateFormat),
|
||||
agentBirthDate: this.dateUtils.formatDate(raw.agentBirthDate, dateFormat),
|
||||
agentOpeningBalance: raw.agentOpeningBalance || 0,
|
||||
homeBranch: raw.homeBranch,
|
||||
tdsApplicable: raw.tdsApplicable === 'Yes',
|
||||
tdsPercent: raw.tdsPercent || undefined,
|
||||
savingBranch: raw.savingBranch,
|
||||
transferBranch: raw.transferBranch || undefined,
|
||||
transferAmountAccountType: raw.transferAmountAccountType || undefined,
|
||||
transferAccountNo: raw.transferAccountNo || undefined,
|
||||
commissionCalculation: raw.commissionCalculation === 'Yes',
|
||||
limit: raw.limit || undefined,
|
||||
machineRent: raw.machineRent || undefined,
|
||||
agentSecurityBranch: raw.agentSecurityBranch || undefined,
|
||||
agentSecurityAccountType: raw.agentSecurityAccountType || undefined,
|
||||
agentSecurityAccountNo: raw.agentSecurityAccountNo || undefined,
|
||||
otherCommission: raw.otherCommission || undefined,
|
||||
agentDeposit: raw.agentDeposit || undefined,
|
||||
festivalAdvance: raw.festivalAdvance || undefined,
|
||||
otherDeduction: raw.otherDeduction || undefined,
|
||||
dateFormat,
|
||||
locale,
|
||||
limits: (raw.limits || []).map((limit: any) => ({
|
||||
fromDate: this.dateUtils.getDate(limit.fromDate),
|
||||
toDate: this.dateUtils.getDate(limit.toDate),
|
||||
limit: limit.limit
|
||||
})),
|
||||
guarantors: (raw.guarantors || []).map((guarantor: any) => ({
|
||||
clientId: Number(guarantor.clientId),
|
||||
guarantorName: guarantor.guarantorName,
|
||||
address1: guarantor.address1,
|
||||
address2: guarantor.address2 || undefined,
|
||||
city: guarantor.city,
|
||||
pinCode: guarantor.pinCode,
|
||||
telephone: guarantor.telephone || undefined
|
||||
}))
|
||||
};
|
||||
|
||||
if (this.agentId) {
|
||||
this.organizationService.updateAgent(this.agentId, payload).subscribe(() => this.exit());
|
||||
} else {
|
||||
this.organizationService.createAgent(payload).subscribe(() => this.exit());
|
||||
}
|
||||
}
|
||||
|
||||
private patchFormFromAgent(agent: any): void {
|
||||
this.agentId = agent.id;
|
||||
this.agentForm.patchValue({
|
||||
clientId: agent.clientId,
|
||||
agentCode: agent.agentCode,
|
||||
agentNameId: agent.agentNameId,
|
||||
agentAddress1: agent.agentAddress1,
|
||||
agentAddress2: agent.agentAddress2,
|
||||
agentCity: agent.agentCity,
|
||||
agentPinCode: agent.agentPinCode,
|
||||
agentTelephone: agent.agentTelephone,
|
||||
agentSavingAccountType: agent.agentSavingAccountType,
|
||||
agentSavingAccountNo: agent.agentSavingAccountNo,
|
||||
agentOpeningDate: agent.agentOpeningDate ? new Date(agent.agentOpeningDate) : null,
|
||||
agentBirthDate: agent.agentBirthDate ? new Date(agent.agentBirthDate) : null,
|
||||
agentCurrentBalance: agent.agentCurrentBalance,
|
||||
agentOpeningBalance: agent.agentOpeningBalance,
|
||||
homeBranch: agent.homeBranch,
|
||||
tdsApplicable: agent.tdsApplicable ? 'Yes' : 'No',
|
||||
tdsPercent: agent.tdsPercent,
|
||||
currentTds: agent.currentTds,
|
||||
tdsAmount: agent.tdsAmount,
|
||||
savingBranch: agent.savingBranch,
|
||||
transferBranch: agent.transferBranch,
|
||||
transferAmountAccountType: agent.transferAmountAccountType,
|
||||
transferAccountNo: agent.transferAccountNo,
|
||||
commissionCalculation: agent.commissionCalculation ? 'Yes' : 'No',
|
||||
limit: agent.limit,
|
||||
machineRent: agent.machineRent,
|
||||
agentSecurityBranch: agent.agentSecurityBranch,
|
||||
agentSecurityAccountType: agent.agentSecurityAccountType,
|
||||
agentSecurityAccountNo: agent.agentSecurityAccountNo,
|
||||
commission: agent.commission,
|
||||
otherCommission: agent.otherCommission,
|
||||
agentDeposit: agent.agentDeposit,
|
||||
festivalAdvance: agent.festivalAdvance,
|
||||
otherDeduction: agent.otherDeduction
|
||||
});
|
||||
|
||||
this.limits.clear();
|
||||
(agent.limits || []).forEach((limit: any) => {
|
||||
const group = this.buildLimitGroup();
|
||||
group.patchValue({
|
||||
fromDate: limit.fromDate ? new Date(limit.fromDate) : null,
|
||||
toDate: limit.toDate ? new Date(limit.toDate) : null,
|
||||
limit: limit.limit
|
||||
});
|
||||
this.limits.push(group);
|
||||
});
|
||||
|
||||
this.guarantors.clear();
|
||||
(agent.guarantors || []).forEach((guarantor: any) => {
|
||||
const group = this.buildGuarantorGroup();
|
||||
group.patchValue(guarantor);
|
||||
this.guarantors.push(group);
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user