Skip to content

WEB-954: Migrate Subscription management : products#3640

Open
alberto-art3ch wants to merge 1 commit into
openMF:devfrom
alberto-art3ch:WEB-954/migrate-subscription-management-products
Open

WEB-954: Migrate Subscription management : products#3640
alberto-art3ch wants to merge 1 commit into
openMF:devfrom
alberto-art3ch:WEB-954/migrate-subscription-management-products

Conversation

@alberto-art3ch

@alberto-art3ch alberto-art3ch commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

Description

Replace manual subscribe/unsubscribe patterns with DestroyRef + takeUntilDestroyed across products components and directives. Also replace UntypedFormBuilder/Group/Control/Array with typed Angular equivalents.

Related issues and discussion

WEB-954

Screenshots, if any

Checklist

Please make sure these boxes are checked before submitting your pull request - thanks!

  • If you have multiple commits please combine them into one commit by squashing them.

  • Read and understood the contribution guidelines at web-app/.github/CONTRIBUTING.md.

Summary by CodeRabbit

  • Refactor
    • Migrated reactive forms to stronger typing across product management screens for more reliable form behavior and validation.
    • Introduced lifecycle-aware subscription cleanup throughout components to prevent lingering listeners, improving stability and reducing memory leaks.

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown

Review Change Stack

Note

.coderabbit.yaml has unrecognized properties

CodeRabbit is using all valid settings from your configuration. Unrecognized properties (listed below) have been ignored and may indicate typos or deprecated fields that can be removed.

⚠️ Parsing warnings (1)
Validation error: Unrecognized key: "pre_merge_checks"
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Walkthrough

Many product-area components were migrated from Angular untyped reactive forms to typed Form* APIs and now inject DestroyRef and use takeUntilDestroyed to auto-unsubscribe route.data and valueChanges subscriptions.

Changes

Angular products refactor

Layer / File(s) Summary
Typed forms & lifecycle subscriptions (product-wide)
src/app/products/...
Bulk migration: untyped reactive forms → typed FormBuilder/FormGroup/FormControl/FormArray; ActivatedRoute.data and many valueChanges subscriptions now use pipe(takeUntilDestroyed(this.destroyRef)) with injected DestroyRef.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • openMF/web-app#3487: Overlapping changes to near-breach/working-capital components and typed form migrations.
  • openMF/web-app#3493: Related edits around loan-product currency/multiples and subscription handling.
  • openMF/web-app#3461: Related working-capital breach model/service typing and route-data handling.

Suggested reviewers

  • adamsaghy
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/app/products/share-products/share-product-stepper/share-product-terms-step/share-product-terms-step.component.ts (1)

45-56: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Missing teardown on combineLatest form subscription.

valueChanges streams are long-lived; this subscription should be lifecycle-bound like the rest of this PR to avoid leaks across navigations.

Suggested fix
-    combineLatest([
+    combineLatest([
       this.shareProductTermsForm.get('sharesIssued').valueChanges,
       this.shareProductTermsForm.get('unitPrice').valueChanges
-    ]).subscribe(
+    ])
+      .pipe(takeUntilDestroyed(this.destroyRef))
+      .subscribe(
       ([
         sharesIssued,
         unitPrice
       ]: number[]) => {
         this.shareProductTermsForm.get('shareCapital').setValue(sharesIssued * unitPrice);
       }
-    );
+    );

As per coding guidelines, for src/app/** you asked to “verify ... clean observable patterns.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/app/products/share-products/share-product-stepper/share-product-terms-step/share-product-terms-step.component.ts`
around lines 45 - 56, The combineLatest subscription created in ngOnInit
(listening to this.shareProductTermsForm.get('sharesIssued').valueChanges and
.get('unitPrice').valueChanges) is not torn down and will leak; update the
implementation to make the observable lifecycle-bound by piping the combined
stream through a teardown operator (for example pipe(takeUntil(this.destroy$))
using a component-level Subject destroy$ that is completed in ngOnDestroy, or
store the Subscription returned and unsubscribe in ngOnDestroy), then keep the
logic that sets
this.shareProductTermsForm.get('shareCapital').setValue(sharesIssued *
unitPrice) inside that subscription; ensure destroy$ (or the unsubscribe) is
defined on the component and invoked in ngOnDestroy.

Source: Coding guidelines

🧹 Nitpick comments (19)
src/app/products/loan-products/working-capital/breach-configuration/view-breach-configuration/view-breach-configuration.component.ts (1)

35-36: ⚡ Quick win

Narrow route.data typing to Breach instead of any.

{ breachData: any } discards type safety even though breachData is already modeled as Breach | null.
As per coding guidelines: "src/app/**/*.ts: Use TypeScript for all application code with strict typing conventions." Based on learnings: avoid any and define concrete response/data shapes.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/app/products/loan-products/working-capital/breach-configuration/view-breach-configuration/view-breach-configuration.component.ts`
around lines 35 - 36, The subscription currently types the route data as {
breachData: any } which loses type safety; update the typing to { breachData:
Breach | null } (matching the component's breachData property) and import the
Breach model/interface, then update the this.route.data.pipe(...).subscribe
signature accordingly (leave takeUntilDestroyed(this.destroyRef) and the
assignment to this.breachData intact); ensure any other usages in
view-breach-configuration.component.ts that rely on breachData reflect the
stronger type.

Sources: Coding guidelines, Learnings

src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-details-step/recurring-deposit-product-details-step.component.ts (1)

32-32: ⚡ Quick win

Use a typed controls map for recurringDepositProductDetailsForm.

Switching to FormGroup is good, but without control generics this remains loosely typed and value/patchValue checks stay weaker than intended.
As per coding guidelines: "src/app/**/*.ts: Use TypeScript for all application code with strict typing conventions."

Also applies to: 36-36

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-details-step/recurring-deposit-product-details-step.component.ts`
at line 32, The recurringDepositProductDetailsForm is currently an untyped
FormGroup — create a typed controls interface (e.g.
RecurringDepositProductDetailsFormControls) describing each control and its
FormControl type, then initialize the form using that interface so the form
variable is strongly typed (use
FormBuilder.group<RecurringDepositProductDetailsFormControls>(...) or new
FormGroup<RecurringDepositProductDetailsFormControls>(...)); update usages of
recurringDepositProductDetailsForm.value/patchValue to match the new typed shape
and adjust the private formBuilder = inject(FormBuilder) usage only to build the
strongly-typed form.

Source: Coding guidelines

src/app/products/loan-products/working-capital/near-breach-configuration/view-near-breach-configuration/view-near-breach-configuration.component.ts (1)

37-38: ⚡ Quick win

Replace any in route-data typing with NearBreach.

The new subscription still uses any ({ nearBreachData: any }). Please type it as { nearBreachData: NearBreach } (or NearBreach | null if resolver can return null) to keep strict typing guarantees intact.

As per coding guidelines: src/app/**/*.ts: “Use TypeScript for all application code with strict typing conventions.” Based on learnings: avoid any for API/route response shapes in TypeScript files.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/app/products/loan-products/working-capital/near-breach-configuration/view-near-breach-configuration/view-near-breach-configuration.component.ts`
around lines 37 - 38, The route data subscription currently types the payload as
{ nearBreachData: any } — update it to a strict type such as { nearBreachData:
NearBreach } (or { nearBreachData: NearBreach | null } if resolver may return
null) in the subscribe callback for route.data.pipe(...).subscribe, and ensure
the NearBreach interface/type is imported or defined in this component; also
update the component property this.nearBreachData to that same type so usages
inside view-near-breach-configuration.component.ts are type-safe.

Sources: Coding guidelines, Learnings

src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-interest-rate-chart-step/recurring-deposit-product-interest-rate-chart-step.component.ts (1)

95-95: 🏗️ Heavy lift

Finish strong typing for chart form controls (generics + typed value models).

The shift away from Untyped* is good, but current FormGroup/FormArray usage is still largely unbounded. Defining typed control/value interfaces for chart/slab/incentive structures would prevent invalid shape assumptions when reading/writing nested controls.

As per coding guidelines: src/app/**/*.ts: “Use TypeScript for all application code with strict typing conventions.”

Also applies to: 334-336, 382-384, 386-430

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-interest-rate-chart-step/recurring-deposit-product-interest-rate-chart-step.component.ts`
at line 95, The chart form is declared as an untyped FormGroup
(recurringDepositProductInterestRateChartForm) and several nested
arrays/controls are unbounded; define TypeScript interfaces for the chart, slab
and incentive models (e.g., RecurringDepositInterestChart, InterestSlab,
Incentive) and update the form types to use generics such as
FormGroup<RecurringDepositInterestChart>, FormArray<FormGroup<InterestSlab>> and
typed FormControl<T> for individual fields in methods that build/read the form
(look for places that create slabs/incentives and where values are read/written
around recurringDepositProductInterestRateChartForm); then update all accesses
to use the typed properties so the compiler enforces correct shapes and you can
safely map between form.value and your domain models.

Source: Coding guidelines

src/app/products/manage-delinquency-buckets/delinquency-bucket/edit-bucket/edit-bucket.component.ts (1)

72-72: 🏗️ Heavy lift

Use explicit form and resolver interfaces in the edit flow as well.

The migration still leaves bucketForm: FormGroup and resolver payload members as any. Please type these explicitly (ideally shared with the create component) so create/edit stay consistent and compiler-checked.

As per coding guidelines: src/app/**/*.ts: “Use TypeScript for all application code with strict typing conventions.” Based on learnings: avoid any response typing and model API/route shapes with interfaces.

Also applies to: 102-123

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/app/products/manage-delinquency-buckets/delinquency-bucket/edit-bucket/edit-bucket.component.ts`
at line 72, The component currently declares bucketForm: FormGroup and leaves
resolver payloads as any; update EditBucketComponent to use a concrete form
interface (e.g., BucketForm or shared IBucketForm used by the create component)
and type the FormGroup as FormGroup<BucketForm> (or FormGroup<Record<...>>
matching your controls), and replace any resolver/route payload typings with
explicit interfaces (e.g., IBucketResolverData) instead of any so the component
methods that reference bucketForm, the resolver data, and related members are
fully typed and consistent with the create flow.

Sources: Coding guidelines, Learnings

src/app/products/manage-delinquency-buckets/delinquency-bucket/view-bucket/view-bucket.component.ts (1)

38-38: ⚡ Quick win

Type delinquencyBucket route data explicitly instead of any.

Please replace { delinquencyBucket: any } and delinquencyBucketData: any with the concrete bucket interface/model to preserve strict typing in this view path.

As per coding guidelines: src/app/**/*.ts: “Use TypeScript for all application code with strict typing conventions.” Based on learnings: avoid any for response payloads and prefer concrete interfaces.

Also applies to: 42-43

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/app/products/manage-delinquency-buckets/delinquency-bucket/view-bucket/view-bucket.component.ts`
at line 38, Replace the loose any types with the concrete DelinquencyBucket
interface: import or define the DelinquencyBucket model and change the route
data typing from { delinquencyBucket: any } to { delinquencyBucket:
DelinquencyBucket } and change the component property delinquencyBucketData: any
to delinquencyBucketData: DelinquencyBucket; also update any other occurrences
on lines referenced (e.g., the ActivatedRoute.data subscription or snapshot
access in the constructor/ngOnInit) to use DelinquencyBucket so the component
(view-bucket.component) and its route data are strictly typed.

Sources: Coding guidelines, Learnings

src/app/products/manage-delinquency-buckets/delinquency-bucket/create-bucket/create-bucket.component.ts (1)

72-72: 🏗️ Heavy lift

Complete the typed-forms migration by removing remaining untyped surfaces.

bucketForm: FormGroup and { delinquencyBucketsTemplateData: any } are still loosely typed. Define a concrete form model (e.g., FormGroup<{ name: FormControl<string>; ... }>), and type resolver payloads explicitly to prevent silent shape drift.

As per coding guidelines: src/app/**/*.ts: “Use TypeScript for all application code with strict typing conventions.” Based on learnings: avoid any response typing and introduce specific interfaces/types.

Also applies to: 96-111

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/app/products/manage-delinquency-buckets/delinquency-bucket/create-bucket/create-bucket.component.ts`
at line 72, The form and template payload are still untyped: replace the loose
bucketForm: FormGroup and the { delinquencyBucketsTemplateData: any } payload
with a concrete typed model (e.g., FormGroup<{ name: FormControl<string>;
description: FormControl<string | null>; ... }>) and a specific interface for
the resolver payload (e.g., DelinquencyBucketsTemplateData { /* fields */ });
update create-bucket.component.ts usages (bucketForm, any references to
delinquencyBucketsTemplateData, and methods that read/write controls like
buildForm/createForm/initForm) to use the new types so all form.controls and
resolver responses are strictly typed and prevent implicit any/shape drift.

Sources: Coding guidelines, Learnings

src/app/products/manage-delinquency-buckets/delinquency-bucket/delinquency-bucket.component.ts (1)

60-60: ⚡ Quick win

Tighten any types on resolver data and table source.

delinquencyBucketData, MatTableDataSource<any>, and { delinquencyBuckets: any } should be replaced with the concrete bucket type used by this screen. This keeps the new lifecycle cleanup changes aligned with strict typing.

As per coding guidelines: src/app/**/*.ts: “Use TypeScript for all application code with strict typing conventions.” Based on learnings: prefer specific interfaces over any for response shapes.

Also applies to: 67-67, 76-77

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/app/products/manage-delinquency-buckets/delinquency-bucket/delinquency-bucket.component.ts`
at line 60, The fields and generics using any should be replaced with the
concrete bucket type used by this screen: define or import the DelinquencyBucket
interface and replace delinquencyBucketData: any with the properly typed
resolver shape (e.g. { delinquencyBuckets: DelinquencyBucket[] }), change
MatTableDataSource<any> to MatTableDataSource<DelinquencyBucket>, and update any
resolver/route data typings and usages (including the symbol delinquencyBuckets
and the table data source instantiation in the component) so all occurrences use
DelinquencyBucket instead of any.

Sources: Coding guidelines, Learnings

src/app/products/recurring-deposit-products/recurring-deposit-products.component.ts (1)

217-228: ⚡ Quick win

Bind afterClosed() to component lifecycle as well.

afterClosed() is still a naked subscription. If the component is destroyed before the dialog closes, this callback can still run and mutate state/navigation after teardown.

♻️ Suggested change
-    nextStepDialogRef.afterClosed().subscribe((response: { nextStep: boolean }) => {
+    nextStepDialogRef
+      .afterClosed()
+      .pipe(takeUntilDestroyed(this.destroyRef))
+      .subscribe((response: { nextStep: boolean }) => {
       if (response.nextStep) {
         this.configurationWizardService.showRecurringDepositProductsPage = false;
         this.configurationWizardService.showRecurringDepositProductsList = false;
         this.configurationWizardService.showManageFunds = true;
         this.router.navigate(['/organization']);
       } else {
         this.configurationWizardService.showRecurringDepositProductsPage = false;
         this.configurationWizardService.showRecurringDepositProductsList = false;
         this.router.navigate(['/home']);
       }
-    });
+      });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/app/products/recurring-deposit-products/recurring-deposit-products.component.ts`
around lines 217 - 228, The subscription to nextStepDialogRef.afterClosed() is
not tied to the component lifecycle and may run after teardown; modify the
component to use a destruction signal (e.g., a private destroy$ Subject and
implement ngOnDestroy) and pipe the afterClosed() observable through
takeUntil(this.destroy$) (or use first() where appropriate) before subscribing,
so the callback that updates configurationWizardService and calls
router.navigate is automatically unsubscribed when the component is destroyed;
update or add ngOnDestroy to emit/complete destroy$ and remove any direct naked
subscriptions.
src/app/products/manage-tax-groups/view-tax-group/view-tax-group.component.ts (1)

43-44: ⚡ Quick win

Replace route-data any typing with a concrete interface.

The teardown migration is good, but the new subscription still keeps any in the route contract, which weakens strict typing and propagates unsafe access.

♻️ Suggested change
+interface ViewTaxGroupRouteData {
+  taxGroup: TaxGroup;
+}
+
 export class ViewTaxGroupComponent {
@@
-  taxGroupData: any;
+  taxGroupData: TaxGroup;
@@
-    this.route.data.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { taxGroup: any }) => {
+    this.route.data.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: ViewTaxGroupRouteData) => {
       this.taxGroupData = data.taxGroup;
     });
   }
 }

As per coding guidelines, src/app/**/*.ts: Use TypeScript for all application code with strict typing conventions. Based on learnings, avoid Observable<any> response typing and introduce specific interfaces for response shapes.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/app/products/manage-tax-groups/view-tax-group/view-tax-group.component.ts`
around lines 43 - 44, Replace the any typing on the route data with a concrete
interface: define an interface (e.g., TaxGroup or TaxGroupRouteData) describing
the expected properties (id, name, members, etc.) and use it in the subscription
and component property declarations so the subscription becomes
this.route.data.pipe(...).subscribe((data: { taxGroup: TaxGroup }) => {
this.taxGroupData = data.taxGroup; }) and change the type of taxGroupData
accordingly; also update any resolver or route typing that provides
data.taxGroup to return the same TaxGroup interface to keep types consistent
across ViewTaxGroupComponent and its resolver.

Sources: Coding guidelines, Learnings

src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-terms-step/recurring-deposit-product-terms-step.component.ts (1)

34-34: ⚡ Quick win

Use a strongly typed FormGroup model instead of raw FormGroup.

The migration removes untyped forms, but FormGroup without a control map still leaves this form effectively weakly typed.

As per coding guidelines, src/app/**/*.ts: Use TypeScript for all application code with strict typing conventions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-terms-step/recurring-deposit-product-terms-step.component.ts`
at line 34, Replace the untyped recurringDepositProductTermsForm: FormGroup with
a strongly typed form model: define an interface (e.g.,
RecurringDepositProductTermsFormControls) that lists each control name and its
FormControl type (e.g., FormControl<number | null> or FormControl<string | null>
as appropriate), then change the field to recurringDepositProductTermsForm:
FormGroup<RecurringDepositProductTermsFormControls> and update the
formBuilder.group(...) initialization to use that generic so each control (names
used in this component) is strongly typed; ensure you import
FormControl/FormGroup types and adjust any code that reads controls to use the
typed keys.

Source: Coding guidelines

src/app/products/saving-products/saving-product-stepper/saving-product-charges-step/saving-product-charges-step.component.ts (1)

66-66: ⚡ Quick win

Consider adding a generic type parameter to FormControl for full type safety.

The FormControl type can accept a generic type parameter to specify the value type (e.g., FormControl<string>). This would provide better type safety and IDE support.

♻️ Example with generic type
-@Input() currencyCode: FormControl;
+@Input() currencyCode: FormControl<string>;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/app/products/saving-products/saving-product-stepper/saving-product-charges-step/saving-product-charges-step.component.ts`
at line 66, The Input property currencyCode uses a raw FormControl which lacks
value-type information; update the declaration for currencyCode to use a
FormControl generic with the correct value type (e.g., FormControl<string> or
FormControl<string | null> depending on whether null is allowed) so the
component and consumers get full type safety and better IDE completions; locate
the currencyCode Input in saving-product-charges-step.component.ts and change
its type accordingly and adjust any callers/initializations to match the tighter
type.
src/app/products/saving-products/saving-product-stepper/saving-product-details-step/saving-product-details-step.component.ts (1)

36-36: ⚡ Quick win

Consider adding a generic type parameter to FormGroup for full type safety.

The FormGroup can accept a generic type parameter to describe the form shape. This provides better type safety for .value, .patchValue(), and form control access.

♻️ Example with interface
interface SavingProductDetailsForm {
  name: string;
  shortName: string;
  description: string;
}

savingProductDetailsForm: FormGroup<{
  name: FormControl<string>;
  shortName: FormControl<string>;
  description: FormControl<string>;
}>;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/app/products/saving-products/saving-product-stepper/saving-product-details-step/saving-product-details-step.component.ts`
at line 36, The savingProductDetailsForm is declared as an untyped FormGroup;
add a generic type describing the form shape to gain full type-safety (e.g.,
create an interface or inline type for fields like name, shortName, description
and change savingProductDetailsForm: FormGroup to FormGroup<{ name:
FormControl<string>; shortName: FormControl<string>; description:
FormControl<string>; }>) and update where the form is created/initialized
(constructor or ngOnInit) to use FormControl<string> and typed controls so
.value, .patchValue(), and control access (savingProductDetailsForm.get or
savingProductDetailsForm.controls) are correctly typed.
src/app/products/saving-products/saving-product-stepper/saving-product-terms-step/saving-product-terms-step.component.ts (1)

34-34: ⚡ Quick win

Consider adding a generic type parameter to FormGroup for full type safety.

Similar to the details step, this FormGroup would benefit from a generic type parameter describing the form controls (nominalAnnualInterestRate, interestCompoundingPeriodType, etc.) for better type safety.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/app/products/saving-products/saving-product-stepper/saving-product-terms-step/saving-product-terms-step.component.ts`
at line 34, The savingProductTermsForm property should declare a typed FormGroup
to get full type safety: update savingProductTermsForm to use FormGroup with a
generic describing the controls (e.g., keys like nominalAnnualInterestRate,
interestCompoundingPeriodType, interestCalculationType,
interestPostingPeriodType, minOpenBalanceRequired, maxOpenBalanceAllowed, etc.)
and their control types (FormControl<number | string | boolean> or
AbstractControl<number | string | boolean> as appropriate). Locate the
savingProductTermsForm declaration in the SavingProductTermsStepComponent and
change the type from FormGroup to FormGroup<{ <controlName>:
AbstractControl<...>; ... }> so the component, validators, and value accessors
are strongly typed throughout.
src/app/products/collaterals/create-collateral/create-collateral.component.ts (1)

43-43: ⚡ Quick win

Use a strongly-typed FormGroup instead of a bare FormGroup.

The current declaration still leaves control/value access loosely typed, so this migration does not enforce strict form typing yet.

♻️ Suggested typing upgrade
-import { FormGroup, FormBuilder, Validators } from '`@angular/forms`';
+import { FormBuilder, FormControl, FormGroup, Validators } from '`@angular/forms`';

+type CollateralFormModel = {
+  name: FormControl<string>;
+  unitType: FormControl<string>;
+  basePrice: FormControl<string>;
+  pctToBase: FormControl<string>;
+  currency: FormControl<string>;
+  quality: FormControl<string>;
+};

-  collateralForm: FormGroup;
+  collateralForm: FormGroup<CollateralFormModel>;

  createCollateralForm() {
-    this.collateralForm = this.formBuilder.group({
+    this.collateralForm = this.formBuilder.nonNullable.group({
       name: [
         '',
         Validators.required
       ],
...

As per coding guidelines, src/app/**/*.ts: “Use TypeScript for all application code with strict typing conventions.”

Also applies to: 78-104

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/app/products/collaterals/create-collateral/create-collateral.component.ts`
at line 43, The collateralForm is declared as an untyped FormGroup; declare a
strongly-typed form model and update collateralForm to use FormGroup<T> (or
FormGroup<Record<key, FormControlType>>) so control access is typed. Create an
interface (e.g. CollateralFormModel) listing each control name and its type
(string, number, boolean, or specific value types), then initialize the form
with the typed builder (e.g. this.collateralForm =
this.fb.group<CollateralFormModel>({...}) or use NonNullableFormBuilder for
non-nullable controls), replacing bare FormControl/FormBuilder usages in the
component (collateralForm, FormBuilder initialization and form creation logic in
create-collateral.component) so everywhere you reference controls (get, value,
patchValue) benefits from strict typing.

Source: Coding guidelines

src/app/products/collaterals/edit-collateral/edit-collateral.component.ts (1)

42-42: ⚡ Quick win

Complete the typed-forms migration with a typed control map.

collateralForm: FormGroup keeps control access weakly typed; use FormGroup<...> (with typed controls) so value/patchValue are checked at compile time.

As per coding guidelines, src/app/**/*.ts: “Use TypeScript for all application code with strict typing conventions.”

Also applies to: 68-95

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/products/collaterals/edit-collateral/edit-collateral.component.ts` at
line 42, The collateralForm is currently declared as an untyped FormGroup;
replace it with a typed FormGroup describing each control (e.g. FormGroup<{
title: FormControl<string|null>, description: FormControl<string|null>, amount:
FormControl<number|null>, ... }>) and update its initialization in the component
(where you call new FormGroup(...) or this.fb.group(...)) to use FormControl<T>
(or this.fb.control<T>) and proper Validators so value/patchValue are
type-checked; adjust any usages in methods like the constructor/init block and
the code between the previously noted range (the form build and any
patchValue/value calls around lines 68-95) to match the new control types and
imports (FormGroup, FormControl, Validators) so compile-time checking enforces
correct shapes.

Source: Coding guidelines

src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-interest-rate-chart-step/fixed-deposit-product-interest-rate-chart-step.component.ts (1)

96-97: 🏗️ Heavy lift

Define typed nested form models for charts/slabs/incentives.

This migration removes Untyped*, but unparameterized FormGroup/FormArray across nested methods still permits shape drift and weak value typing. A typed model for chart/slab/incentive controls would make this conversion materially safer.

As per coding guidelines, src/app/**/*.ts: “Use TypeScript for all application code with strict typing conventions.”

Also applies to: 328-333, 376-427

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-interest-rate-chart-step/fixed-deposit-product-interest-rate-chart-step.component.ts`
around lines 96 - 97, Declare TypeScript interfaces for the nested form models
(e.g., FixedDepositChartModel, FixedDepositSlabModel,
FixedDepositIncentiveModel), then parameterize all untyped FormGroup and
FormArray instances and factory methods to use those interfaces (for example
change fixedDepositProductInterestRateChartForm: FormGroup to
FormGroup<FixedDepositChartModel> and
FormArray<FormGroup<FixedDepositSlabModel>> for slabs, etc.); update the
form-building helper methods that create chart/slab/incentive controls (the
functions that currently return plain FormGroup/FormArray instances) to return
typed FormGroup<T>/FormArray<T> and adjust any getters and usages to treat
.value as the typed model rather than any. Ensure all nested push/insert calls
and value reads/writes are updated to the corresponding typed interfaces so the
compiler enforces the shape across the chart/slab/incentive code paths.

Source: Coding guidelines

src/app/products/deposit-product-incentive-form-dialog/deposit-product-incentive-form-dialog.component.ts (1)

56-56: ⚡ Quick win

Apply strict typing to the dialog form and valueChanges payload.

The component switched away from Untyped*, but FormGroup is still untyped and attributeName is any, so type safety is still mostly opt-out.

As per coding guidelines, src/app/**/*.ts: “Use TypeScript for all application code with strict typing conventions.”

Also applies to: 95-105, 108-132

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/app/products/deposit-product-incentive-form-dialog/deposit-product-incentive-form-dialog.component.ts`
at line 56, Declare a typed form model interface (e.g.
DepositProductIncentiveFormModel) that lists each control (attributeName:
string, amount: number, operator: string, type: string, etc.), change
depositProductIncentiveForm from untyped FormGroup to
FormGroup<DepositProductIncentiveFormModel> (or use FormBuilder.group with typed
controls), replace any occurrences of attributeName: any with attributeName:
string, and update the valueChanges subscription to accept a strongly-typed
payload (value: DepositProductIncentiveFormModel) so all downstream usages
inside the component (including the logic currently handling valueChanges) are
statically typed.

Source: Coding guidelines

src/app/products/loan-products/loan-product-stepper/loan-product-accounting-step/loan-product-accounting-step.component.ts (1)

681-688: ⚡ Quick win

Remove no-op subscription with empty if/else blocks.

The advancedAccountingRules subscription in the working-capital branch subscribes to value changes but contains empty if/else blocks that perform no actions. This is dead code that wastes resources.

♻️ Proposed fix

Remove the entire subscription since it has no side effects:

           this.loanProductAccountingForm.addControl('advancedAccountingRules', new FormControl(false));
-
-          this.loanProductAccountingForm
-            .get('advancedAccountingRules')
-            .valueChanges.pipe(takeUntilDestroyed(this.destroyRef))
-            .subscribe((advancedAccountingRules: boolean) => {
-              if (advancedAccountingRules) {
-              } else {
-              }
-            });
         }
       });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/app/products/loan-products/loan-product-stepper/loan-product-accounting-step/loan-product-accounting-step.component.ts`
around lines 681 - 688, The subscription to
this.loanProductAccountingForm.get('advancedAccountingRules').valueChanges
(chained with .pipe(takeUntilDestroyed(this.destroyRef)).subscribe(...))
contains no-op if/else blocks and should be removed to eliminate dead code and
unnecessary subscriptions; locate the subscribe call in
loan-product-accounting-step.component.ts (the valueChanges subscription on
advancedAccountingRules) and delete the entire subscription block, or if
behavior was intended, replace the empty if/else with the actual handling logic
for advancedAccountingRules inside the subscribe callback.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/app/products/charges/create-charge/create-charge.component.ts`:
- Around line 183-185: The current code mutates this.chargePaymentModeData in
place when filtering for Working Capital, causing subsequent chargeAppliesTo
changes to work on an already-narrowed list; fix by keeping an immutable source
list and assigning a filtered copy to the UI field instead of mutating it. Add
or use a preserved array (e.g., this.allChargePaymentModeData or
this._originalChargePaymentModeData) populated once, then in the handler for
chargeAppliesTo set this.chargePaymentModeData =
this._originalChargePaymentModeData.filter(...) when filtering for id === 0 and
otherwise restore the full list via this.chargePaymentModeData =
[...this._originalChargePaymentModeData]; ensure all references in
create-charge.component.ts (chargePaymentModeData, chargeAppliesTo) use this
assignment pattern rather than in-place .filter on the UI array.
- Around line 254-275: The switch handling for chargeAppliesTo can try to add an
already-existing control 'chargePaymentMode' (e.g., cases 1 and 5). Update the
logic in the create-charge.component.ts switch so before calling
this.chargeForm.addControl('chargePaymentMode', ...) you check whether the
control exists (this.chargeForm.get('chargePaymentMode') or contains) and only
add when absent; likewise, use removeControl only if the control exists. Apply
the existence checks around addControl/removeControl for 'chargePaymentMode'
(and similarly for 'incomeAccountId' if desired) in the switch block handling
chargeAppliesTo.

In `@src/app/products/charges/edit-charge/edit-charge.component.ts`:
- Line 205: The taxGroupId FormControl is initialized to an empty string which
breaks the submit cleanup that expects a falsy/null value when no tax group is
selected; change the initialization in chargeForm.addControl('taxGroupId', ...)
to create the control with a null value (e.g., this.formBuilder.control(null))
so charges.taxGroupId.value is null when unset and the existing submit logic
that removes/omits empty taxGroupId will work correctly.

In
`@src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-accounting-step/fixed-deposit-product-accounting-step.component.ts`:
- Around line 225-311: The form currently calls addControl unconditionally when
accountingRule becomes 2 or 3, causing "control already exists" errors and
re-creating the nested advancedAccountingRules subscription on toggles; update
setConditionalControls to check for existing controls before adding (e.g., use
fixedDepositProductAccountingForm.contains('advancedAccountingRules') or
equivalent) and only call addControl for 'savingsReferenceAccountId',
'savingsControlAccountId', 'transfersInSuspenseAccountId',
'interestOnSavingsAccountId', 'incomeFromFeeAccountId',
'incomeFromPenaltyAccountId', 'feesReceivableAccountId',
'penaltiesReceivableAccountId', 'interestPayableAccountId' when they don't
already exist; likewise only attach the advancedAccountingRules.valueChanges
subscription once when you create that control (or guard subscription creation
with a flag/contains check) and keep the existing logic to remove related
mapping arrays ('paymentChannelToFundSourceMappings',
'feeToIncomeAccountMappings', 'penaltyToIncomeAccountMappings') when
advancedAccountingRules is false.

In
`@src/app/products/floating-rates/create-floating-rate/create-floating-rate.component.ts`:
- Around line 94-95: The component uses bare FormGroup and untyped form-related
data which loses compile-time shape information; change floatingRateForm in
CreateFloatingRateComponent to FormGroup<FloatingRateFormControls> (define
FloatingRateFormControls with name/isBaseLendingRate/isActive), update
createFloatingRatePeriodsForm() to return FormGroup<FloatingRateFormControls>
(or the correct controls type), and replace floatingRatePeriodForm in
FloatingRatePeriodDialogComponent with
FormGroup<FloatingRatePeriodDialogControls> (define
fromDate/interestRate/isDifferentialToBaseLendingRate types); also type
floatingRatePeriodsData (use a FloatingRatePeriod model),
MatTableDataSource<FloatingRatePeriod>, and the dialog afterClosed()
subscription to expect the typed dialog payload instead of any so form values
and dialog payloads are strictly typed end-to-end (update related method
signatures and service/dialog open/close payload types accordingly).

In
`@src/app/products/loan-products/working-capital/breach-configuration/create-breach-configuration/create-breach-configuration.component.ts`:
- Line 40: breachForm is untyped and route data/service methods use any; define
a concrete interface for the route payload (e.g., BreachTemplate {
breachFrequencyTypeOptions: StringEnumOptionData[];
breachAmountCalculationTypeOptions: StringEnumOptionData[]; ... }) and update
the route.data subscription signature to subscribe((data: { breachTemplate?:
BreachTemplate }) => ...) , replace breachForm: FormGroup with a strongly-typed
FormGroup e.g., FormGroup<{ name: FormControl<string>; breachFrequency:
FormControl<number>; breachFrequencyType: FormControl<string>;
breachAmountCalculationType: FormControl<string>; breachAmount:
FormControl<number> }> so getRawValue() returns a typed object, and update
ProductsService.createWrokingCapitalBreach(payload: any): Observable<any> to use
typed request/response interfaces (e.g., CreateBreachPayload /
CreateBreachResponse) and adjust usages accordingly
(create-breach-configuration.component.ts should pass the typed payload and
handle the typed response).

In
`@src/app/products/loan-products/working-capital/breach-configuration/edit-breach-configuration/edit-breach-configuration.component.ts`:
- Line 37: The breachForm field is untyped and the route data uses any; define a
typed interface for the route data payload (e.g., include breachTemplate and its
properties used by breachFrequencyTypeOptions and
breachAmountCalculationTypeOptions) and update the component to use that
interface for ActivatedRoute.data, then change breachForm: FormGroup to a
strongly typed FormGroup specifying the control keys and their types (e.g.,
FormGroup<{ controlName: FormControl<Type>; ... }>), ensuring the control names
match those used when building the form in this component (breachForm) and that
breachFrequencyTypeOptions and breachAmountCalculationTypeOptions are typed to
the option types from the route-data interface so all usages are strongly typed.

In
`@src/app/products/loan-products/working-capital/near-breach-configuration/create-near-breach-configuration/create-near-breach-configuration.component.ts`:
- Line 40: Replace untyped route data and FormGroup usage by declaring concrete
interfaces (e.g., NearBreachRouteData with breachTemplate and
breachFrequencyTypeOptions, and NearBreachFormValue describing the form fields)
and use them in the component: change nearBreachForm: FormGroup to
nearBreachForm: FormGroup<NearBreachFormValue>, update the ActivatedRoute
subscription signature from (data: { breachTemplate?: any }) to (data:
NearBreachRouteData) and stop using breachTemplate ?? {} fallback typing, and
then rely on the typed this.nearBreachForm.getRawValue() (or cast only where
necessary) so the payload and template fields are strongly typed throughout the
create-near-breach-configuration.component (references: nearBreachForm,
getRawValue(), breachTemplate, breachFrequencyTypeOptions, route.data).

In
`@src/app/products/loan-products/working-capital/near-breach-configuration/edit-near-breach-configuration/edit-near-breach-configuration.component.ts`:
- Line 37: The form and route data are untyped: change nearBreachForm: FormGroup
to a typed FormGroup<FormGroup<{...}>>/FormControl types that reflect the
payload used with getRawValue(), and replace the any in route.data.subscribe(...
breachTemplate: any ...) with a specific interface (e.g., an interface
containing breachFrequencyTypeOptions: StringEnumOptionData[]) so
breachFrequencyTypeOptions is strongly typed; apply the same fixes in
create-near-breach-configuration.component.ts (typed nearBreachForm and typed
breachTemplate) and update any form building and submit code to use the new
typed controls instead of untyped FormGroup/getRawValue usage.

In
`@src/app/products/manage-tax-components/create-tax-component/create-tax-component.component.ts`:
- Around line 117-130: When account type fields change, the code currently calls
FormGroup.addControl for 'debitAccountId'/'creditAccountId' which doesn't
replace existing controls and can leave stale values; update the subscriptions
on taxComponentForm.get('debitAccountType') and
taxComponentForm.get('creditAccountType') to use FormGroup.setControl (or
removeControl + addControl) so the control is replaced, and if the incoming type
is unset/empty remove the corresponding control entirely; keep using
getAccountsData to populate debitAccountData/creditAccountData and preserve the
existing takeUntilDestroyed(this.destroyRef) teardown.

In
`@src/app/products/saving-products/saving-product-stepper/saving-product-accounting-step/saving-product-accounting-step.component.ts`:
- Around line 214-320: The setConditionalControls function re-adds controls and
nests subscriptions every time accountingRule changes; fix it by (1) guarding
addControl/removeControl calls with existence checks (use
savingProductAccountingForm.contains(...) or check get(...) === null) so you
only add controls if missing and only remove if present, and (2) avoid creating
repeated inner subscriptions for allowOverdraft, isDormancyTrackingActive and
advancedAccountingRules by moving those valueChanges subscriptions out of the
accountingRule.valueChanges callback (subscribe once in setConditionalControls)
or by tracking and unsubscribing previous inner subscriptions (store them as
class properties and call unsubscribe before creating a new one) while keeping
takeUntilDestroyed on all top-level subscriptions; update references to
accountingRule, allowOverdraft, isDormancyTrackingActive,
advancedAccountingRules, addControl and removeControl accordingly.

---

Outside diff comments:
In
`@src/app/products/share-products/share-product-stepper/share-product-terms-step/share-product-terms-step.component.ts`:
- Around line 45-56: The combineLatest subscription created in ngOnInit
(listening to this.shareProductTermsForm.get('sharesIssued').valueChanges and
.get('unitPrice').valueChanges) is not torn down and will leak; update the
implementation to make the observable lifecycle-bound by piping the combined
stream through a teardown operator (for example pipe(takeUntil(this.destroy$))
using a component-level Subject destroy$ that is completed in ngOnDestroy, or
store the Subscription returned and unsubscribe in ngOnDestroy), then keep the
logic that sets
this.shareProductTermsForm.get('shareCapital').setValue(sharesIssued *
unitPrice) inside that subscription; ensure destroy$ (or the unsubscribe) is
defined on the component and invoked in ngOnDestroy.

---

Nitpick comments:
In
`@src/app/products/collaterals/create-collateral/create-collateral.component.ts`:
- Line 43: The collateralForm is declared as an untyped FormGroup; declare a
strongly-typed form model and update collateralForm to use FormGroup<T> (or
FormGroup<Record<key, FormControlType>>) so control access is typed. Create an
interface (e.g. CollateralFormModel) listing each control name and its type
(string, number, boolean, or specific value types), then initialize the form
with the typed builder (e.g. this.collateralForm =
this.fb.group<CollateralFormModel>({...}) or use NonNullableFormBuilder for
non-nullable controls), replacing bare FormControl/FormBuilder usages in the
component (collateralForm, FormBuilder initialization and form creation logic in
create-collateral.component) so everywhere you reference controls (get, value,
patchValue) benefits from strict typing.

In `@src/app/products/collaterals/edit-collateral/edit-collateral.component.ts`:
- Line 42: The collateralForm is currently declared as an untyped FormGroup;
replace it with a typed FormGroup describing each control (e.g. FormGroup<{
title: FormControl<string|null>, description: FormControl<string|null>, amount:
FormControl<number|null>, ... }>) and update its initialization in the component
(where you call new FormGroup(...) or this.fb.group(...)) to use FormControl<T>
(or this.fb.control<T>) and proper Validators so value/patchValue are
type-checked; adjust any usages in methods like the constructor/init block and
the code between the previously noted range (the form build and any
patchValue/value calls around lines 68-95) to match the new control types and
imports (FormGroup, FormControl, Validators) so compile-time checking enforces
correct shapes.

In
`@src/app/products/deposit-product-incentive-form-dialog/deposit-product-incentive-form-dialog.component.ts`:
- Line 56: Declare a typed form model interface (e.g.
DepositProductIncentiveFormModel) that lists each control (attributeName:
string, amount: number, operator: string, type: string, etc.), change
depositProductIncentiveForm from untyped FormGroup to
FormGroup<DepositProductIncentiveFormModel> (or use FormBuilder.group with typed
controls), replace any occurrences of attributeName: any with attributeName:
string, and update the valueChanges subscription to accept a strongly-typed
payload (value: DepositProductIncentiveFormModel) so all downstream usages
inside the component (including the logic currently handling valueChanges) are
statically typed.

In
`@src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-interest-rate-chart-step/fixed-deposit-product-interest-rate-chart-step.component.ts`:
- Around line 96-97: Declare TypeScript interfaces for the nested form models
(e.g., FixedDepositChartModel, FixedDepositSlabModel,
FixedDepositIncentiveModel), then parameterize all untyped FormGroup and
FormArray instances and factory methods to use those interfaces (for example
change fixedDepositProductInterestRateChartForm: FormGroup to
FormGroup<FixedDepositChartModel> and
FormArray<FormGroup<FixedDepositSlabModel>> for slabs, etc.); update the
form-building helper methods that create chart/slab/incentive controls (the
functions that currently return plain FormGroup/FormArray instances) to return
typed FormGroup<T>/FormArray<T> and adjust any getters and usages to treat
.value as the typed model rather than any. Ensure all nested push/insert calls
and value reads/writes are updated to the corresponding typed interfaces so the
compiler enforces the shape across the chart/slab/incentive code paths.

In
`@src/app/products/loan-products/loan-product-stepper/loan-product-accounting-step/loan-product-accounting-step.component.ts`:
- Around line 681-688: The subscription to
this.loanProductAccountingForm.get('advancedAccountingRules').valueChanges
(chained with .pipe(takeUntilDestroyed(this.destroyRef)).subscribe(...))
contains no-op if/else blocks and should be removed to eliminate dead code and
unnecessary subscriptions; locate the subscribe call in
loan-product-accounting-step.component.ts (the valueChanges subscription on
advancedAccountingRules) and delete the entire subscription block, or if
behavior was intended, replace the empty if/else with the actual handling logic
for advancedAccountingRules inside the subscribe callback.

In
`@src/app/products/loan-products/working-capital/breach-configuration/view-breach-configuration/view-breach-configuration.component.ts`:
- Around line 35-36: The subscription currently types the route data as {
breachData: any } which loses type safety; update the typing to { breachData:
Breach | null } (matching the component's breachData property) and import the
Breach model/interface, then update the this.route.data.pipe(...).subscribe
signature accordingly (leave takeUntilDestroyed(this.destroyRef) and the
assignment to this.breachData intact); ensure any other usages in
view-breach-configuration.component.ts that rely on breachData reflect the
stronger type.

In
`@src/app/products/loan-products/working-capital/near-breach-configuration/view-near-breach-configuration/view-near-breach-configuration.component.ts`:
- Around line 37-38: The route data subscription currently types the payload as
{ nearBreachData: any } — update it to a strict type such as { nearBreachData:
NearBreach } (or { nearBreachData: NearBreach | null } if resolver may return
null) in the subscribe callback for route.data.pipe(...).subscribe, and ensure
the NearBreach interface/type is imported or defined in this component; also
update the component property this.nearBreachData to that same type so usages
inside view-near-breach-configuration.component.ts are type-safe.

In
`@src/app/products/manage-delinquency-buckets/delinquency-bucket/create-bucket/create-bucket.component.ts`:
- Line 72: The form and template payload are still untyped: replace the loose
bucketForm: FormGroup and the { delinquencyBucketsTemplateData: any } payload
with a concrete typed model (e.g., FormGroup<{ name: FormControl<string>;
description: FormControl<string | null>; ... }>) and a specific interface for
the resolver payload (e.g., DelinquencyBucketsTemplateData { /* fields */ });
update create-bucket.component.ts usages (bucketForm, any references to
delinquencyBucketsTemplateData, and methods that read/write controls like
buildForm/createForm/initForm) to use the new types so all form.controls and
resolver responses are strictly typed and prevent implicit any/shape drift.

In
`@src/app/products/manage-delinquency-buckets/delinquency-bucket/delinquency-bucket.component.ts`:
- Line 60: The fields and generics using any should be replaced with the
concrete bucket type used by this screen: define or import the DelinquencyBucket
interface and replace delinquencyBucketData: any with the properly typed
resolver shape (e.g. { delinquencyBuckets: DelinquencyBucket[] }), change
MatTableDataSource<any> to MatTableDataSource<DelinquencyBucket>, and update any
resolver/route data typings and usages (including the symbol delinquencyBuckets
and the table data source instantiation in the component) so all occurrences use
DelinquencyBucket instead of any.

In
`@src/app/products/manage-delinquency-buckets/delinquency-bucket/edit-bucket/edit-bucket.component.ts`:
- Line 72: The component currently declares bucketForm: FormGroup and leaves
resolver payloads as any; update EditBucketComponent to use a concrete form
interface (e.g., BucketForm or shared IBucketForm used by the create component)
and type the FormGroup as FormGroup<BucketForm> (or FormGroup<Record<...>>
matching your controls), and replace any resolver/route payload typings with
explicit interfaces (e.g., IBucketResolverData) instead of any so the component
methods that reference bucketForm, the resolver data, and related members are
fully typed and consistent with the create flow.

In
`@src/app/products/manage-delinquency-buckets/delinquency-bucket/view-bucket/view-bucket.component.ts`:
- Line 38: Replace the loose any types with the concrete DelinquencyBucket
interface: import or define the DelinquencyBucket model and change the route
data typing from { delinquencyBucket: any } to { delinquencyBucket:
DelinquencyBucket } and change the component property delinquencyBucketData: any
to delinquencyBucketData: DelinquencyBucket; also update any other occurrences
on lines referenced (e.g., the ActivatedRoute.data subscription or snapshot
access in the constructor/ngOnInit) to use DelinquencyBucket so the component
(view-bucket.component) and its route data are strictly typed.

In
`@src/app/products/manage-tax-groups/view-tax-group/view-tax-group.component.ts`:
- Around line 43-44: Replace the any typing on the route data with a concrete
interface: define an interface (e.g., TaxGroup or TaxGroupRouteData) describing
the expected properties (id, name, members, etc.) and use it in the subscription
and component property declarations so the subscription becomes
this.route.data.pipe(...).subscribe((data: { taxGroup: TaxGroup }) => {
this.taxGroupData = data.taxGroup; }) and change the type of taxGroupData
accordingly; also update any resolver or route typing that provides
data.taxGroup to return the same TaxGroup interface to keep types consistent
across ViewTaxGroupComponent and its resolver.

In
`@src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-details-step/recurring-deposit-product-details-step.component.ts`:
- Line 32: The recurringDepositProductDetailsForm is currently an untyped
FormGroup — create a typed controls interface (e.g.
RecurringDepositProductDetailsFormControls) describing each control and its
FormControl type, then initialize the form using that interface so the form
variable is strongly typed (use
FormBuilder.group<RecurringDepositProductDetailsFormControls>(...) or new
FormGroup<RecurringDepositProductDetailsFormControls>(...)); update usages of
recurringDepositProductDetailsForm.value/patchValue to match the new typed shape
and adjust the private formBuilder = inject(FormBuilder) usage only to build the
strongly-typed form.

In
`@src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-interest-rate-chart-step/recurring-deposit-product-interest-rate-chart-step.component.ts`:
- Line 95: The chart form is declared as an untyped FormGroup
(recurringDepositProductInterestRateChartForm) and several nested
arrays/controls are unbounded; define TypeScript interfaces for the chart, slab
and incentive models (e.g., RecurringDepositInterestChart, InterestSlab,
Incentive) and update the form types to use generics such as
FormGroup<RecurringDepositInterestChart>, FormArray<FormGroup<InterestSlab>> and
typed FormControl<T> for individual fields in methods that build/read the form
(look for places that create slabs/incentives and where values are read/written
around recurringDepositProductInterestRateChartForm); then update all accesses
to use the typed properties so the compiler enforces correct shapes and you can
safely map between form.value and your domain models.

In
`@src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-terms-step/recurring-deposit-product-terms-step.component.ts`:
- Line 34: Replace the untyped recurringDepositProductTermsForm: FormGroup with
a strongly typed form model: define an interface (e.g.,
RecurringDepositProductTermsFormControls) that lists each control name and its
FormControl type (e.g., FormControl<number | null> or FormControl<string | null>
as appropriate), then change the field to recurringDepositProductTermsForm:
FormGroup<RecurringDepositProductTermsFormControls> and update the
formBuilder.group(...) initialization to use that generic so each control (names
used in this component) is strongly typed; ensure you import
FormControl/FormGroup types and adjust any code that reads controls to use the
typed keys.

In
`@src/app/products/recurring-deposit-products/recurring-deposit-products.component.ts`:
- Around line 217-228: The subscription to nextStepDialogRef.afterClosed() is
not tied to the component lifecycle and may run after teardown; modify the
component to use a destruction signal (e.g., a private destroy$ Subject and
implement ngOnDestroy) and pipe the afterClosed() observable through
takeUntil(this.destroy$) (or use first() where appropriate) before subscribing,
so the callback that updates configurationWizardService and calls
router.navigate is automatically unsubscribed when the component is destroyed;
update or add ngOnDestroy to emit/complete destroy$ and remove any direct naked
subscriptions.

In
`@src/app/products/saving-products/saving-product-stepper/saving-product-charges-step/saving-product-charges-step.component.ts`:
- Line 66: The Input property currencyCode uses a raw FormControl which lacks
value-type information; update the declaration for currencyCode to use a
FormControl generic with the correct value type (e.g., FormControl<string> or
FormControl<string | null> depending on whether null is allowed) so the
component and consumers get full type safety and better IDE completions; locate
the currencyCode Input in saving-product-charges-step.component.ts and change
its type accordingly and adjust any callers/initializations to match the tighter
type.

In
`@src/app/products/saving-products/saving-product-stepper/saving-product-details-step/saving-product-details-step.component.ts`:
- Line 36: The savingProductDetailsForm is declared as an untyped FormGroup; add
a generic type describing the form shape to gain full type-safety (e.g., create
an interface or inline type for fields like name, shortName, description and
change savingProductDetailsForm: FormGroup to FormGroup<{ name:
FormControl<string>; shortName: FormControl<string>; description:
FormControl<string>; }>) and update where the form is created/initialized
(constructor or ngOnInit) to use FormControl<string> and typed controls so
.value, .patchValue(), and control access (savingProductDetailsForm.get or
savingProductDetailsForm.controls) are correctly typed.

In
`@src/app/products/saving-products/saving-product-stepper/saving-product-terms-step/saving-product-terms-step.component.ts`:
- Line 34: The savingProductTermsForm property should declare a typed FormGroup
to get full type safety: update savingProductTermsForm to use FormGroup with a
generic describing the controls (e.g., keys like nominalAnnualInterestRate,
interestCompoundingPeriodType, interestCalculationType,
interestPostingPeriodType, minOpenBalanceRequired, maxOpenBalanceAllowed, etc.)
and their control types (FormControl<number | string | boolean> or
AbstractControl<number | string | boolean> as appropriate). Locate the
savingProductTermsForm declaration in the SavingProductTermsStepComponent and
change the type from FormGroup to FormGroup<{ <controlName>:
AbstractControl<...>; ... }> so the component, validators, and value accessors
are strongly typed throughout.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

Comment thread src/app/products/charges/create-charge/create-charge.component.ts Outdated
Comment thread src/app/products/charges/create-charge/create-charge.component.ts
Comment thread src/app/products/charges/edit-charge/edit-charge.component.ts
@alberto-art3ch alberto-art3ch force-pushed the WEB-954/migrate-subscription-management-products branch from d7e9548 to 3a8fb4e Compare June 10, 2026 02:58

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (6)
src/app/products/manage-tax-components/view-tax-component/view-tax-component.component.ts (1)

38-38: ⚡ Quick win

Consider typing the tax component data.

Both taxComponentData (line 38) and the route-data callback parameter (line 45) are typed as any. Per the project learning, introduce a specific interface for the tax component shape and update the resolver and component accordingly for stronger type safety.

Also applies to: 45-45

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/app/products/manage-tax-components/view-tax-component/view-tax-component.component.ts`
at line 38, Define a concrete interface (e.g., TaxComponent) representing the
tax component shape (fields used in view-tax-component.component.ts and the
resolver), replace the loose any types with that interface for the component
property taxComponentData and for the ActivatedRoute data callback parameter,
and update the resolver method return type to resolve to TaxComponent (or {
taxComponent: TaxComponent } if you return an object); then adjust usages in
ViewTaxComponentComponent (constructor/ngOnInit / route.data subscription) to
use the new type to ensure compile-time safety.

Source: Learnings

src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-details-step/recurring-deposit-product-details-step.component.ts (1)

34-34: ⚡ Quick win

Consider stronger typing for the form.

The recurringDepositProductsTemplate input (line 34) is typed as any, and the FormGroup (line 36) is not parameterized with a form interface. For stronger type safety, consider:

  1. Creating an interface for the template shape
  2. Parameterizing FormGroup with a form-value interface (e.g., FormGroup<RecurringDepositDetailsForm>)

Also applies to: 36-36

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-details-step/recurring-deposit-product-details-step.component.ts`
at line 34, The recurringDepositProductsTemplate input is currently typed as any
and the FormGroup on this component is untyped; create a concrete interface
describing the template shape (e.g., interface RecurringDepositProductsTemplate
{ ... }) and a form value interface (e.g., interface RecurringDepositDetailsForm
{ fieldA: string; fieldB: number; ... }), then update the component to use these
types by changing the Input to recurringDepositProductsTemplate:
RecurringDepositProductsTemplate and parameterizing the form:
FormGroup<RecurringDepositDetailsForm> (identify and update places referencing
recurringDepositProductsTemplate and the FormGroup initialization to match the
new interfaces).

Sources: Coding guidelines, Learnings

src/app/products/loan-products/working-capital/near-breach-configuration/view-near-breach-configuration/view-near-breach-configuration.component.ts (1)

37-37: ⚡ Quick win

Consider typing the route data callback parameter.

The nearBreachData is typed as any. Per the project learning, introduce a specific interface for the route-data shape instead of any, and update the resolver accordingly for stronger type safety.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/app/products/loan-products/working-capital/near-breach-configuration/view-near-breach-configuration/view-near-breach-configuration.component.ts`
at line 37, Introduce a concrete interface (e.g., NearBreachRouteData {
nearBreachData: NearBreachDataType }) to replace the use of `any`, update the
resolver that populates `nearBreachData` to return that typed shape, and change
the `route.data.pipe(...).subscribe((data: { nearBreachData: any }) => {`
callback to use the new interface (e.g., subscribe((data: NearBreachRouteData)
=> {)). Ensure `NearBreachDataType` matches the actual fields returned by the
resolver and export it so both the resolver and the component import and share
the same type for full type safety.

Source: Learnings

src/app/products/saving-products/view-saving-product/view-saving-product.component.ts (1)

33-33: ⚡ Quick win

Consider typing the datatable data.

The savingProductDatatables array (line 33), route-data callback parameter (line 36), and forEach loop variable (line 38) are all typed as any. Per the project learning, introduce a specific interface for the datatable shape and update the resolver and component accordingly for stronger type safety.

Also applies to: 36-36, 38-38

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/app/products/saving-products/view-saving-product/view-saving-product.component.ts`
at line 33, The savingProductDatatables array and related route-data callback
and forEach loop use the unsafe any type; define a specific interface (e.g.,
SavingProductDatatable or ISavingProductRow) that captures the datatable shape
(fields used in the component/resolver), replace the any declarations on
savingProductDatatables, the ActivatedRoute data callback parameter, and the
forEach iterator with that interface, and update the resolver method that
supplies the route data to return Observable/Promise of that typed structure so
the component can consume strongly typed data (adjust imports and signatures for
SavingProductDatatable in view-saving-product.component and the resolver).

Source: Learnings

src/app/products/share-products/share-product-stepper/share-product-accounting-step/share-product-accounting-step.component.ts (1)

39-41: ⚡ Quick win

Consider stronger typing for inputs and form.

Multiple areas use any typing:

  • Input properties (lines 39-41)
  • Account data properties (lines 45-48)
  • The accountingRule callback parameter (line 87)
  • The FormGroup is not parameterized (line 43)

Per the project learning and strict typing guidelines, consider introducing specific interfaces for the template shapes, account data, and parameterizing FormGroup with a form-value interface (e.g., FormGroup<ShareProductAccountingForm>).

Also applies to: 43-43, 45-48, 87-87

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/app/products/share-products/share-product-stepper/share-product-accounting-step/share-product-accounting-step.component.ts`
around lines 39 - 41, Several inputs and the form use any; define explicit
interfaces (e.g., ShareProductsTemplate, AccountingRuleData,
ShareProductAccountingForm) that describe the shapes used by `@Input`()
shareProductsTemplate, `@Input`() accountingRuleData and the form value, then
replace the any types and the untyped FormGroup with typed versions (e.g.,
FormGroup<ShareProductAccountingForm>), and update the accountingRule callback
parameter to use the appropriate interface instead of any so references to
accountingRule, shareProductsTemplate, accountingRuleData and the FormGroup are
all strongly typed.

Sources: Coding guidelines, Learnings

src/app/products/products-mix/products-mix.component.ts (1)

65-65: ⚡ Quick win

Consider typing the products data.

The productMixData (line 65), dataSource generic parameter (line 69), and route-data callback parameter (line 80) are all typed as any. Per the project learning, introduce a specific interface for the product-mix shape and update the resolver, component, and table data source accordingly for stronger type safety.

Also applies to: 69-69, 80-80

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/products/products-mix/products-mix.component.ts` at line 65,
Introduce a concrete interface (e.g. ProductMix or ProductMixItem) describing
the shape of each product-mix entry and replace the any types: change the
component property productMixData: any to productMixData: ProductMix[] (or
ProductMix), update the MatTableDataSource generic (dataSource:
MatTableDataSource<ProductMix>) and change the ActivatedRoute data callback
parameter to accept the typed resolver result (route.data.subscribe((data: {
productMix: ProductMix[] }) => ...)). Also update the resolver return type to
Promise/Observable<ProductMix[]> (or appropriate shape) so the types flow
end-to-end.

Source: Learnings

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@src/app/products/loan-products/working-capital/near-breach-configuration/view-near-breach-configuration/view-near-breach-configuration.component.ts`:
- Line 37: Introduce a concrete interface (e.g., NearBreachRouteData {
nearBreachData: NearBreachDataType }) to replace the use of `any`, update the
resolver that populates `nearBreachData` to return that typed shape, and change
the `route.data.pipe(...).subscribe((data: { nearBreachData: any }) => {`
callback to use the new interface (e.g., subscribe((data: NearBreachRouteData)
=> {)). Ensure `NearBreachDataType` matches the actual fields returned by the
resolver and export it so both the resolver and the component import and share
the same type for full type safety.

In
`@src/app/products/manage-tax-components/view-tax-component/view-tax-component.component.ts`:
- Line 38: Define a concrete interface (e.g., TaxComponent) representing the tax
component shape (fields used in view-tax-component.component.ts and the
resolver), replace the loose any types with that interface for the component
property taxComponentData and for the ActivatedRoute data callback parameter,
and update the resolver method return type to resolve to TaxComponent (or {
taxComponent: TaxComponent } if you return an object); then adjust usages in
ViewTaxComponentComponent (constructor/ngOnInit / route.data subscription) to
use the new type to ensure compile-time safety.

In `@src/app/products/products-mix/products-mix.component.ts`:
- Line 65: Introduce a concrete interface (e.g. ProductMix or ProductMixItem)
describing the shape of each product-mix entry and replace the any types: change
the component property productMixData: any to productMixData: ProductMix[] (or
ProductMix), update the MatTableDataSource generic (dataSource:
MatTableDataSource<ProductMix>) and change the ActivatedRoute data callback
parameter to accept the typed resolver result (route.data.subscribe((data: {
productMix: ProductMix[] }) => ...)). Also update the resolver return type to
Promise/Observable<ProductMix[]> (or appropriate shape) so the types flow
end-to-end.

In
`@src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-details-step/recurring-deposit-product-details-step.component.ts`:
- Line 34: The recurringDepositProductsTemplate input is currently typed as any
and the FormGroup on this component is untyped; create a concrete interface
describing the template shape (e.g., interface RecurringDepositProductsTemplate
{ ... }) and a form value interface (e.g., interface RecurringDepositDetailsForm
{ fieldA: string; fieldB: number; ... }), then update the component to use these
types by changing the Input to recurringDepositProductsTemplate:
RecurringDepositProductsTemplate and parameterizing the form:
FormGroup<RecurringDepositDetailsForm> (identify and update places referencing
recurringDepositProductsTemplate and the FormGroup initialization to match the
new interfaces).

In
`@src/app/products/saving-products/view-saving-product/view-saving-product.component.ts`:
- Line 33: The savingProductDatatables array and related route-data callback and
forEach loop use the unsafe any type; define a specific interface (e.g.,
SavingProductDatatable or ISavingProductRow) that captures the datatable shape
(fields used in the component/resolver), replace the any declarations on
savingProductDatatables, the ActivatedRoute data callback parameter, and the
forEach iterator with that interface, and update the resolver method that
supplies the route data to return Observable/Promise of that typed structure so
the component can consume strongly typed data (adjust imports and signatures for
SavingProductDatatable in view-saving-product.component and the resolver).

In
`@src/app/products/share-products/share-product-stepper/share-product-accounting-step/share-product-accounting-step.component.ts`:
- Around line 39-41: Several inputs and the form use any; define explicit
interfaces (e.g., ShareProductsTemplate, AccountingRuleData,
ShareProductAccountingForm) that describe the shapes used by `@Input`()
shareProductsTemplate, `@Input`() accountingRuleData and the form value, then
replace the any types and the untyped FormGroup with typed versions (e.g.,
FormGroup<ShareProductAccountingForm>), and update the accountingRule callback
parameter to use the appropriate interface instead of any so references to
accountingRule, shareProductsTemplate, accountingRuleData and the FormGroup are
all strongly typed.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 09ffcbb3-2552-4de5-869e-4796c8531f6b

📥 Commits

Reviewing files that changed from the base of the PR and between d7e9548 and 3a8fb4e.

📒 Files selected for processing (115)
  • src/app/products/charges/charges.component.ts
  • src/app/products/charges/create-charge/create-charge.component.ts
  • src/app/products/charges/edit-charge/edit-charge.component.ts
  • src/app/products/charges/view-charge/view-charge.component.ts
  • src/app/products/collaterals/collaterals.component.ts
  • src/app/products/collaterals/create-collateral/create-collateral.component.ts
  • src/app/products/collaterals/edit-collateral/edit-collateral.component.ts
  • src/app/products/collaterals/view-collateral/view-collateral.component.ts
  • src/app/products/deposit-product-incentive-form-dialog/deposit-product-incentive-form-dialog.component.ts
  • src/app/products/fixed-deposit-products/create-fixed-deposit-product/create-fixed-deposit-product.component.ts
  • src/app/products/fixed-deposit-products/edit-fixed-deposit-product/edit-fixed-deposit-product.component.ts
  • src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-accounting-step/fixed-deposit-product-accounting-step.component.ts
  • src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-charges-step/fixed-deposit-product-charges-step.component.ts
  • src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-currency-step/fixed-deposit-product-currency-step.component.ts
  • src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-details-step/fixed-deposit-product-details-step.component.ts
  • src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-interest-rate-chart-step/fixed-deposit-product-interest-rate-chart-step.component.ts
  • src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-settings-step/fixed-deposit-product-settings-step.component.ts
  • src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-terms-step/fixed-deposit-product-terms-step.component.ts
  • src/app/products/fixed-deposit-products/fixed-deposit-products.component.ts
  • src/app/products/fixed-deposit-products/view-fixed-deposit-product/fixed-deposit-datatable-tab/fixed-deposit-datatable-tab.component.ts
  • src/app/products/fixed-deposit-products/view-fixed-deposit-product/fixed-deposit-general-tab/fixed-deposit-general-tab.component.ts
  • src/app/products/fixed-deposit-products/view-fixed-deposit-product/view-fixed-deposit-product.component.ts
  • src/app/products/floating-rates/create-floating-rate/create-floating-rate.component.ts
  • src/app/products/floating-rates/edit-floating-rate/edit-floating-rate.component.ts
  • src/app/products/floating-rates/floating-rate-period-dialog/floating-rate-period-dialog.component.ts
  • src/app/products/floating-rates/floating-rates.component.ts
  • src/app/products/floating-rates/view-floating-rate/view-floating-rate.component.ts
  • src/app/products/loan-products/create-loan-product/create-loan-product.component.ts
  • src/app/products/loan-products/edit-loan-product/edit-loan-product.component.ts
  • src/app/products/loan-products/import-loan-product-dialog/import-loan-product-dialog.component.ts
  • src/app/products/loan-products/loan-product-stepper/loan-product-accounting-step/advanced-accounting-mapping-rule/advanced-accounting-mapping-rule.component.ts
  • src/app/products/loan-products/loan-product-stepper/loan-product-accounting-step/loan-product-accounting-step.component.ts
  • src/app/products/loan-products/loan-product-stepper/loan-product-capitalized-income-step/loan-product-deferred-income-recognition-step.component.ts
  • src/app/products/loan-products/loan-product-stepper/loan-product-charges-step/loan-product-charges-step.component.ts
  • src/app/products/loan-products/loan-product-stepper/loan-product-currency-step/loan-product-currency-step.component.ts
  • src/app/products/loan-products/loan-product-stepper/loan-product-details-step/loan-product-details-step.component.ts
  • src/app/products/loan-products/loan-product-stepper/loan-product-interest-refund-step/loan-product-interest-refund-step.component.ts
  • src/app/products/loan-products/loan-product-stepper/loan-product-payment-strategy-step/advance-payment-allocation-tab/advance-payment-allocation-tab.component.ts
  • src/app/products/loan-products/loan-product-stepper/loan-product-settings-step/loan-product-settings-step.component.ts
  • src/app/products/loan-products/loan-product-stepper/loan-product-terms-step/loan-product-terms-step.component.ts
  • src/app/products/loan-products/loan-products.component.ts
  • src/app/products/loan-products/view-loan-product/datatable-tab/datatable-tab.component.ts
  • src/app/products/loan-products/view-loan-product/general-tab/general-tab.component.ts
  • src/app/products/loan-products/view-loan-product/view-loan-product.component.ts
  • src/app/products/loan-products/working-capital/breach-configuration/breach-configuration.component.ts
  • src/app/products/loan-products/working-capital/breach-configuration/create-breach-configuration/create-breach-configuration.component.ts
  • src/app/products/loan-products/working-capital/breach-configuration/edit-breach-configuration/edit-breach-configuration.component.ts
  • src/app/products/loan-products/working-capital/breach-configuration/view-breach-configuration/view-breach-configuration.component.ts
  • src/app/products/loan-products/working-capital/near-breach-configuration/create-near-breach-configuration/create-near-breach-configuration.component.ts
  • src/app/products/loan-products/working-capital/near-breach-configuration/edit-near-breach-configuration/edit-near-breach-configuration.component.ts
  • src/app/products/loan-products/working-capital/near-breach-configuration/near-breach-configuration.component.ts
  • src/app/products/loan-products/working-capital/near-breach-configuration/view-near-breach-configuration/view-near-breach-configuration.component.ts
  • src/app/products/loan-products/working-capital/working-capital-product.model.ts
  • src/app/products/manage-delinquency-buckets/delinquency-bucket/create-bucket/create-bucket.component.ts
  • src/app/products/manage-delinquency-buckets/delinquency-bucket/delinquency-bucket.component.ts
  • src/app/products/manage-delinquency-buckets/delinquency-bucket/edit-bucket/edit-bucket.component.ts
  • src/app/products/manage-delinquency-buckets/delinquency-bucket/view-bucket/view-bucket.component.ts
  • src/app/products/manage-delinquency-buckets/delinquency-range/create-range/create-range.component.ts
  • src/app/products/manage-delinquency-buckets/delinquency-range/delinquency-range.component.ts
  • src/app/products/manage-delinquency-buckets/delinquency-range/edit-range/edit-range.component.ts
  • src/app/products/manage-delinquency-buckets/delinquency-range/view-range/view-range.component.ts
  • src/app/products/manage-tax-components/create-tax-component/create-tax-component.component.ts
  • src/app/products/manage-tax-components/edit-tax-component/edit-tax-component.component.ts
  • src/app/products/manage-tax-components/manage-tax-components.component.ts
  • src/app/products/manage-tax-components/view-tax-component/view-tax-component.component.ts
  • src/app/products/manage-tax-groups/create-tax-group/create-tax-group.component.ts
  • src/app/products/manage-tax-groups/edit-tax-group/edit-tax-group.component.ts
  • src/app/products/manage-tax-groups/manage-tax-groups.component.ts
  • src/app/products/manage-tax-groups/view-tax-group/view-tax-group.component.ts
  • src/app/products/products-mix/create-product-mix/create-product-mix.component.ts
  • src/app/products/products-mix/edit-product-mix/edit-product-mix.component.ts
  • src/app/products/products-mix/products-mix.component.ts
  • src/app/products/products-mix/view-product-mix/view-product-mix.component.ts
  • src/app/products/products.service.ts
  • src/app/products/recurring-deposit-products/create-recurring-deposit-product/create-recurring-deposit-product.component.ts
  • src/app/products/recurring-deposit-products/edit-recurring-deposit-product/edit-recurring-deposit-product.component.ts
  • src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-accounting-step/recurring-deposit-product-accounting-step.component.ts
  • src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-charges-step/recurring-deposit-product-charges-step.component.ts
  • src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-currency-step/recurring-deposit-product-currency-step.component.ts
  • src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-details-step/recurring-deposit-product-details-step.component.ts
  • src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-interest-rate-chart-step/recurring-deposit-product-interest-rate-chart-step.component.ts
  • src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-settings-step/recurring-deposit-product-settings-step.component.ts
  • src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-terms-step/recurring-deposit-product-terms-step.component.ts
  • src/app/products/recurring-deposit-products/recurring-deposit-products.component.ts
  • src/app/products/recurring-deposit-products/view-recurring-deposit-product/recurring-deposit-datatable-tab/recurring-deposit-datatable-tab.component.ts
  • src/app/products/recurring-deposit-products/view-recurring-deposit-product/recurring-deposit-general-tab/recurring-deposit-general-tab.component.ts
  • src/app/products/recurring-deposit-products/view-recurring-deposit-product/view-recurring-deposit-product.component.ts
  • src/app/products/saving-products/create-saving-product/create-saving-product.component.ts
  • src/app/products/saving-products/edit-saving-product/edit-saving-product.component.ts
  • src/app/products/saving-products/saving-product-stepper/saving-product-accounting-step/saving-product-accounting-step.component.ts
  • src/app/products/saving-products/saving-product-stepper/saving-product-charges-step/saving-product-charges-step.component.ts
  • src/app/products/saving-products/saving-product-stepper/saving-product-currency-step/saving-product-currency-step.component.ts
  • src/app/products/saving-products/saving-product-stepper/saving-product-details-step/saving-product-details-step.component.ts
  • src/app/products/saving-products/saving-product-stepper/saving-product-settings-step/saving-product-settings-step.component.ts
  • src/app/products/saving-products/saving-product-stepper/saving-product-terms-step/saving-product-terms-step.component.ts
  • src/app/products/saving-products/saving-products.component.ts
  • src/app/products/saving-products/view-saving-product/saving-product-datatable-tab/saving-product-datatable-tab.component.ts
  • src/app/products/saving-products/view-saving-product/saving-product-general-tab/saving-product-general-tab.component.ts
  • src/app/products/saving-products/view-saving-product/view-saving-product.component.ts
  • src/app/products/share-products/create-dividend/create-dividend.component.ts
  • src/app/products/share-products/create-share-product/create-share-product.component.ts
  • src/app/products/share-products/dividends-share-product/dividends.components.ts
  • src/app/products/share-products/edit-share-product/edit-share-product.component.ts
  • src/app/products/share-products/share-product-stepper/share-product-accounting-step/share-product-accounting-step.component.ts
  • src/app/products/share-products/share-product-stepper/share-product-charges-step/share-product-charges-step.component.ts
  • src/app/products/share-products/share-product-stepper/share-product-currency-step/share-product-currency-step.component.ts
  • src/app/products/share-products/share-product-stepper/share-product-details-step/share-product-details-step.component.ts
  • src/app/products/share-products/share-product-stepper/share-product-market-price-step/share-product-market-price-step.component.ts
  • src/app/products/share-products/share-product-stepper/share-product-settings-step/share-product-settings-step.component.ts
  • src/app/products/share-products/share-product-stepper/share-product-terms-step/share-product-terms-step.component.ts
  • src/app/products/share-products/share-products.component.ts
  • src/app/products/share-products/view-dividend/view-dividend.component.ts
  • src/app/products/share-products/view-share-product/share-product-datatable-tab/share-product-datatable-tab.component.ts
  • src/app/products/share-products/view-share-product/share-product-general-tab/share-product-general-tab.component.ts
  • src/app/products/share-products/view-share-product/view-share-product.component.ts
🚧 Files skipped from review as they are similar to previous changes (100)
  • src/app/products/loan-products/working-capital/breach-configuration/view-breach-configuration/view-breach-configuration.component.ts
  • src/app/products/collaterals/collaterals.component.ts
  • src/app/products/share-products/share-product-stepper/share-product-currency-step/share-product-currency-step.component.ts
  • src/app/products/manage-tax-groups/view-tax-group/view-tax-group.component.ts
  • src/app/products/loan-products/loan-product-stepper/loan-product-accounting-step/advanced-accounting-mapping-rule/advanced-accounting-mapping-rule.component.ts
  • src/app/products/floating-rates/floating-rates.component.ts
  • src/app/products/charges/view-charge/view-charge.component.ts
  • src/app/products/loan-products/view-loan-product/general-tab/general-tab.component.ts
  • src/app/products/saving-products/saving-products.component.ts
  • src/app/products/loan-products/loan-product-stepper/loan-product-details-step/loan-product-details-step.component.ts
  • src/app/products/saving-products/saving-product-stepper/saving-product-terms-step/saving-product-terms-step.component.ts
  • src/app/products/loan-products/view-loan-product/datatable-tab/datatable-tab.component.ts
  • src/app/products/loan-products/view-loan-product/view-loan-product.component.ts
  • src/app/products/loan-products/import-loan-product-dialog/import-loan-product-dialog.component.ts
  • src/app/products/loan-products/working-capital/breach-configuration/breach-configuration.component.ts
  • src/app/products/loan-products/working-capital/near-breach-configuration/create-near-breach-configuration/create-near-breach-configuration.component.ts
  • src/app/products/recurring-deposit-products/recurring-deposit-products.component.ts
  • src/app/products/manage-tax-components/manage-tax-components.component.ts
  • src/app/products/fixed-deposit-products/fixed-deposit-products.component.ts
  • src/app/products/manage-tax-groups/create-tax-group/create-tax-group.component.ts
  • src/app/products/products-mix/create-product-mix/create-product-mix.component.ts
  • src/app/products/share-products/view-share-product/share-product-datatable-tab/share-product-datatable-tab.component.ts
  • src/app/products/recurring-deposit-products/edit-recurring-deposit-product/edit-recurring-deposit-product.component.ts
  • src/app/products/recurring-deposit-products/view-recurring-deposit-product/view-recurring-deposit-product.component.ts
  • src/app/products/products-mix/edit-product-mix/edit-product-mix.component.ts
  • src/app/products/loan-products/loan-product-stepper/loan-product-interest-refund-step/loan-product-interest-refund-step.component.ts
  • src/app/products/saving-products/edit-saving-product/edit-saving-product.component.ts
  • src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-terms-step/fixed-deposit-product-terms-step.component.ts
  • src/app/products/saving-products/saving-product-stepper/saving-product-settings-step/saving-product-settings-step.component.ts
  • src/app/products/collaterals/view-collateral/view-collateral.component.ts
  • src/app/products/loan-products/working-capital/breach-configuration/edit-breach-configuration/edit-breach-configuration.component.ts
  • src/app/products/loan-products/working-capital/breach-configuration/create-breach-configuration/create-breach-configuration.component.ts
  • src/app/products/fixed-deposit-products/view-fixed-deposit-product/view-fixed-deposit-product.component.ts
  • src/app/products/charges/charges.component.ts
  • src/app/products/loan-products/loan-product-stepper/loan-product-currency-step/loan-product-currency-step.component.ts
  • src/app/products/saving-products/view-saving-product/saving-product-datatable-tab/saving-product-datatable-tab.component.ts
  • src/app/products/manage-delinquency-buckets/delinquency-bucket/view-bucket/view-bucket.component.ts
  • src/app/products/share-products/view-dividend/view-dividend.component.ts
  • src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-currency-step/recurring-deposit-product-currency-step.component.ts
  • src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-currency-step/fixed-deposit-product-currency-step.component.ts
  • src/app/products/products-mix/view-product-mix/view-product-mix.component.ts
  • src/app/products/deposit-product-incentive-form-dialog/deposit-product-incentive-form-dialog.component.ts
  • src/app/products/manage-delinquency-buckets/delinquency-bucket/delinquency-bucket.component.ts
  • src/app/products/floating-rates/floating-rate-period-dialog/floating-rate-period-dialog.component.ts
  • src/app/products/recurring-deposit-products/view-recurring-deposit-product/recurring-deposit-general-tab/recurring-deposit-general-tab.component.ts
  • src/app/products/manage-delinquency-buckets/delinquency-range/view-range/view-range.component.ts
  • src/app/products/manage-delinquency-buckets/delinquency-range/edit-range/edit-range.component.ts
  • src/app/products/manage-tax-groups/manage-tax-groups.component.ts
  • src/app/products/share-products/share-product-stepper/share-product-charges-step/share-product-charges-step.component.ts
  • src/app/products/share-products/view-share-product/view-share-product.component.ts
  • src/app/products/loan-products/working-capital/near-breach-configuration/edit-near-breach-configuration/edit-near-breach-configuration.component.ts
  • src/app/products/share-products/edit-share-product/edit-share-product.component.ts
  • src/app/products/saving-products/create-saving-product/create-saving-product.component.ts
  • src/app/products/collaterals/create-collateral/create-collateral.component.ts
  • src/app/products/share-products/share-product-stepper/share-product-details-step/share-product-details-step.component.ts
  • src/app/products/fixed-deposit-products/view-fixed-deposit-product/fixed-deposit-datatable-tab/fixed-deposit-datatable-tab.component.ts
  • src/app/products/manage-tax-components/edit-tax-component/edit-tax-component.component.ts
  • src/app/products/fixed-deposit-products/create-fixed-deposit-product/create-fixed-deposit-product.component.ts
  • src/app/products/share-products/share-product-stepper/share-product-market-price-step/share-product-market-price-step.component.ts
  • src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-terms-step/recurring-deposit-product-terms-step.component.ts
  • src/app/products/loan-products/create-loan-product/create-loan-product.component.ts
  • src/app/products/charges/create-charge/create-charge.component.ts
  • src/app/products/loan-products/working-capital/near-breach-configuration/near-breach-configuration.component.ts
  • src/app/products/manage-delinquency-buckets/delinquency-range/create-range/create-range.component.ts
  • src/app/products/recurring-deposit-products/create-recurring-deposit-product/create-recurring-deposit-product.component.ts
  • src/app/products/manage-tax-components/create-tax-component/create-tax-component.component.ts
  • src/app/products/saving-products/saving-product-stepper/saving-product-currency-step/saving-product-currency-step.component.ts
  • src/app/products/floating-rates/create-floating-rate/create-floating-rate.component.ts
  • src/app/products/saving-products/view-saving-product/saving-product-general-tab/saving-product-general-tab.component.ts
  • src/app/products/saving-products/saving-product-stepper/saving-product-charges-step/saving-product-charges-step.component.ts
  • src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-settings-step/recurring-deposit-product-settings-step.component.ts
  • src/app/products/fixed-deposit-products/view-fixed-deposit-product/fixed-deposit-general-tab/fixed-deposit-general-tab.component.ts
  • src/app/products/manage-delinquency-buckets/delinquency-bucket/create-bucket/create-bucket.component.ts
  • src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-charges-step/fixed-deposit-product-charges-step.component.ts
  • src/app/products/recurring-deposit-products/view-recurring-deposit-product/recurring-deposit-datatable-tab/recurring-deposit-datatable-tab.component.ts
  • src/app/products/manage-delinquency-buckets/delinquency-range/delinquency-range.component.ts
  • src/app/products/share-products/dividends-share-product/dividends.components.ts
  • src/app/products/loan-products/loan-products.component.ts
  • src/app/products/share-products/create-share-product/create-share-product.component.ts
  • src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-details-step/fixed-deposit-product-details-step.component.ts
  • src/app/products/floating-rates/edit-floating-rate/edit-floating-rate.component.ts
  • src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-charges-step/recurring-deposit-product-charges-step.component.ts
  • src/app/products/share-products/share-product-stepper/share-product-terms-step/share-product-terms-step.component.ts
  • src/app/products/loan-products/edit-loan-product/edit-loan-product.component.ts
  • src/app/products/loan-products/loan-product-stepper/loan-product-charges-step/loan-product-charges-step.component.ts
  • src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-settings-step/fixed-deposit-product-settings-step.component.ts
  • src/app/products/loan-products/loan-product-stepper/loan-product-capitalized-income-step/loan-product-deferred-income-recognition-step.component.ts
  • src/app/products/share-products/view-share-product/share-product-general-tab/share-product-general-tab.component.ts
  • src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-interest-rate-chart-step/recurring-deposit-product-interest-rate-chart-step.component.ts
  • src/app/products/saving-products/saving-product-stepper/saving-product-accounting-step/saving-product-accounting-step.component.ts
  • src/app/products/manage-delinquency-buckets/delinquency-bucket/edit-bucket/edit-bucket.component.ts
  • src/app/products/saving-products/saving-product-stepper/saving-product-details-step/saving-product-details-step.component.ts
  • src/app/products/collaterals/edit-collateral/edit-collateral.component.ts
  • src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-interest-rate-chart-step/fixed-deposit-product-interest-rate-chart-step.component.ts
  • src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-accounting-step/recurring-deposit-product-accounting-step.component.ts
  • src/app/products/loan-products/loan-product-stepper/loan-product-payment-strategy-step/advance-payment-allocation-tab/advance-payment-allocation-tab.component.ts
  • src/app/products/loan-products/loan-product-stepper/loan-product-accounting-step/loan-product-accounting-step.component.ts
  • src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-accounting-step/fixed-deposit-product-accounting-step.component.ts
  • src/app/products/loan-products/loan-product-stepper/loan-product-settings-step/loan-product-settings-step.component.ts
  • src/app/products/loan-products/loan-product-stepper/loan-product-terms-step/loan-product-terms-step.component.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant