feat: add create share product component (#462)
- Add share product stepper components - Add create share product component - Add datepicker-base.ts Fixes: #190
This commit is contained in:
@@ -19,6 +19,7 @@ import { CreateSavingProductComponent } from './saving-products/create-saving-pr
|
|||||||
import { ViewSavingProductComponent } from './saving-products/view-saving-product/view-saving-product.component';
|
import { ViewSavingProductComponent } from './saving-products/view-saving-product/view-saving-product.component';
|
||||||
import { EditSavingProductComponent } from './saving-products/edit-saving-product/edit-saving-product.component';
|
import { EditSavingProductComponent } from './saving-products/edit-saving-product/edit-saving-product.component';
|
||||||
import { ShareProductsComponent } from './share-products/share-products.component';
|
import { ShareProductsComponent } from './share-products/share-products.component';
|
||||||
|
import { CreateShareProductComponent } from './share-products/create-share-product/create-share-product.component';
|
||||||
import { ManageTaxConfigurationsComponent } from './manage-tax-configurations/manage-tax-configurations.component';
|
import { ManageTaxConfigurationsComponent } from './manage-tax-configurations/manage-tax-configurations.component';
|
||||||
import { RecurringDepositProductsComponent } from './recurring-deposit-products/recurring-deposit-products.component';
|
import { RecurringDepositProductsComponent } from './recurring-deposit-products/recurring-deposit-products.component';
|
||||||
import { ChargesComponent } from './charges/charges.component';
|
import { ChargesComponent } from './charges/charges.component';
|
||||||
@@ -36,6 +37,7 @@ import { SavingProductsTemplateResolver } from './saving-products/saving-product
|
|||||||
import { SavingProductResolver } from './saving-products/saving-product.resolver';
|
import { SavingProductResolver } from './saving-products/saving-product.resolver';
|
||||||
import { SavingProductAndTemplateResolver } from './saving-products/edit-saving-product/saving-product-and-template.resolver';
|
import { SavingProductAndTemplateResolver } from './saving-products/edit-saving-product/saving-product-and-template.resolver';
|
||||||
import { ShareProductsResolver } from './share-products/share-products.resolver';
|
import { ShareProductsResolver } from './share-products/share-products.resolver';
|
||||||
|
import { ShareProductsTemplateResolver } from './share-products/share-products-template.resolver';
|
||||||
import { RecurringDepositProductsResolver } from './recurring-deposit-products/recurring-deposit-products.resolver';
|
import { RecurringDepositProductsResolver } from './recurring-deposit-products/recurring-deposit-products.resolver';
|
||||||
import { ChargesResolver } from './charges/charges.resolver';
|
import { ChargesResolver } from './charges/charges.resolver';
|
||||||
import { FixedDepositProductsResolver } from './fixed-deposit-products/fixed-deposit-products.resolver';
|
import { FixedDepositProductsResolver } from './fixed-deposit-products/fixed-deposit-products.resolver';
|
||||||
@@ -147,6 +149,14 @@ const routes: Routes = [
|
|||||||
resolve: {
|
resolve: {
|
||||||
shareProducts: ShareProductsResolver
|
shareProducts: ShareProductsResolver
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'create',
|
||||||
|
component: CreateShareProductComponent,
|
||||||
|
data: { title: extract('Create Share Product'), breadcrumb: 'Create' },
|
||||||
|
resolve: {
|
||||||
|
shareProductsTemplate: ShareProductsTemplateResolver
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -223,6 +233,7 @@ const routes: Routes = [
|
|||||||
SavingProductResolver,
|
SavingProductResolver,
|
||||||
SavingProductAndTemplateResolver,
|
SavingProductAndTemplateResolver,
|
||||||
ShareProductsResolver,
|
ShareProductsResolver,
|
||||||
|
ShareProductsTemplateResolver,
|
||||||
RecurringDepositProductsResolver,
|
RecurringDepositProductsResolver,
|
||||||
ChargesResolver,
|
ChargesResolver,
|
||||||
FixedDepositProductsResolver,
|
FixedDepositProductsResolver,
|
||||||
|
|||||||
@@ -38,6 +38,15 @@ import { CreateSavingProductComponent } from './saving-products/create-saving-pr
|
|||||||
import { ViewSavingProductComponent } from './saving-products/view-saving-product/view-saving-product.component';
|
import { ViewSavingProductComponent } from './saving-products/view-saving-product/view-saving-product.component';
|
||||||
import { EditSavingProductComponent } from './saving-products/edit-saving-product/edit-saving-product.component';
|
import { EditSavingProductComponent } from './saving-products/edit-saving-product/edit-saving-product.component';
|
||||||
import { ShareProductsComponent } from './share-products/share-products.component';
|
import { ShareProductsComponent } from './share-products/share-products.component';
|
||||||
|
import { ShareProductDetailsStepComponent } from './share-products/share-product-stepper/share-product-details-step/share-product-details-step.component';
|
||||||
|
import { ShareProductCurrencyStepComponent } from './share-products/share-product-stepper/share-product-currency-step/share-product-currency-step.component';
|
||||||
|
import { ShareProductTermsStepComponent } from './share-products/share-product-stepper/share-product-terms-step/share-product-terms-step.component';
|
||||||
|
import { ShareProductSettingsStepComponent } from './share-products/share-product-stepper/share-product-settings-step/share-product-settings-step.component';
|
||||||
|
import { ShareProductMarketPriceStepComponent } from './share-products/share-product-stepper/share-product-market-price-step/share-product-market-price-step.component';
|
||||||
|
import { ShareProductChargesStepComponent } from './share-products/share-product-stepper/share-product-charges-step/share-product-charges-step.component';
|
||||||
|
import { ShareProductAccountingStepComponent } from './share-products/share-product-stepper/share-product-accounting-step/share-product-accounting-step.component';
|
||||||
|
import { ShareProductPreviewStepComponent } from './share-products/share-product-stepper/share-product-preview-step/share-product-preview-step.component';
|
||||||
|
import { CreateShareProductComponent } from './share-products/create-share-product/create-share-product.component';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Products Module
|
* Products Module
|
||||||
@@ -80,7 +89,16 @@ import { ShareProductsComponent } from './share-products/share-products.componen
|
|||||||
CreateSavingProductComponent,
|
CreateSavingProductComponent,
|
||||||
ViewSavingProductComponent,
|
ViewSavingProductComponent,
|
||||||
EditSavingProductComponent,
|
EditSavingProductComponent,
|
||||||
ShareProductsComponent
|
ShareProductsComponent,
|
||||||
|
ShareProductDetailsStepComponent,
|
||||||
|
ShareProductCurrencyStepComponent,
|
||||||
|
ShareProductTermsStepComponent,
|
||||||
|
ShareProductSettingsStepComponent,
|
||||||
|
ShareProductMarketPriceStepComponent,
|
||||||
|
ShareProductChargesStepComponent,
|
||||||
|
ShareProductAccountingStepComponent,
|
||||||
|
ShareProductPreviewStepComponent,
|
||||||
|
CreateShareProductComponent
|
||||||
],
|
],
|
||||||
entryComponents: [
|
entryComponents: [
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -73,6 +73,14 @@ export class ProductsService {
|
|||||||
return this.http.get('/products/share');
|
return this.http.get('/products/share');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createShareProduct(shareProduct: string): Observable<any> {
|
||||||
|
return this.http.post('/products/share', shareProduct);
|
||||||
|
}
|
||||||
|
|
||||||
|
getShareProductsTemplate(): Observable<any> {
|
||||||
|
return this.http.get('/products/share/template');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {Observable<any>} Recurring deposit products data
|
* @returns {Observable<any>} Recurring deposit products data
|
||||||
*/
|
*/
|
||||||
|
|||||||
+106
@@ -0,0 +1,106 @@
|
|||||||
|
<div class="container">
|
||||||
|
|
||||||
|
<mat-horizontal-stepper class="mat-elevation-z8" labelPosition="bottom" #shareProductStepper>
|
||||||
|
|
||||||
|
<ng-template matStepperIcon="number">
|
||||||
|
<fa-icon icon="pencil-alt" size="sm"></fa-icon>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template matStepperIcon="edit">
|
||||||
|
<fa-icon icon="pencil-alt" size="sm"></fa-icon>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template matStepperIcon="done">
|
||||||
|
<fa-icon icon="check" size="sm"></fa-icon>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template matStepperIcon="error">
|
||||||
|
<fa-icon icon="exclamation-triangle" size="lg"></fa-icon>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template matStepperIcon="preview">
|
||||||
|
<fa-icon icon="eye" size="sm"></fa-icon>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<mat-step [stepControl]="shareProductDetailsForm">
|
||||||
|
|
||||||
|
<ng-template matStepLabel>DETAILS</ng-template>
|
||||||
|
|
||||||
|
<mifosx-share-product-details-step></mifosx-share-product-details-step>
|
||||||
|
|
||||||
|
</mat-step>
|
||||||
|
|
||||||
|
<mat-step [stepControl]="shareProductCurrencyForm">
|
||||||
|
|
||||||
|
<ng-template matStepLabel>CURRENCY</ng-template>
|
||||||
|
|
||||||
|
<mifosx-share-product-currency-step [shareProductsTemplate]="shareProductsTemplate"></mifosx-share-product-currency-step>
|
||||||
|
|
||||||
|
</mat-step>
|
||||||
|
|
||||||
|
<mat-step [stepControl]="shareProductTermsForm">
|
||||||
|
|
||||||
|
<ng-template matStepLabel>TERMS</ng-template>
|
||||||
|
|
||||||
|
<mifosx-share-product-terms-step></mifosx-share-product-terms-step>
|
||||||
|
|
||||||
|
</mat-step>
|
||||||
|
|
||||||
|
<mat-step [stepControl]="shareProductSettingsForm">
|
||||||
|
|
||||||
|
<ng-template matStepLabel>SETTINGS</ng-template>
|
||||||
|
|
||||||
|
<mifosx-share-product-settings-step [shareProductsTemplate]="shareProductsTemplate"></mifosx-share-product-settings-step>
|
||||||
|
|
||||||
|
</mat-step>
|
||||||
|
|
||||||
|
<mat-step>
|
||||||
|
|
||||||
|
<ng-template matStepLabel>MARKET PRICE</ng-template>
|
||||||
|
|
||||||
|
<mifosx-share-product-market-price-step></mifosx-share-product-market-price-step>
|
||||||
|
|
||||||
|
</mat-step>
|
||||||
|
|
||||||
|
<mat-step>
|
||||||
|
|
||||||
|
<ng-template matStepLabel>CHARGES</ng-template>
|
||||||
|
|
||||||
|
<mifosx-share-product-charges-step
|
||||||
|
[shareProductsTemplate]="shareProductsTemplate"
|
||||||
|
[currencyCode]="shareProductCurrencyForm.get('currencyCode')"
|
||||||
|
>
|
||||||
|
</mifosx-share-product-charges-step>
|
||||||
|
|
||||||
|
</mat-step>
|
||||||
|
|
||||||
|
<mat-step [stepControl]="shareProductAccountingForm">
|
||||||
|
|
||||||
|
<ng-template matStepLabel>ACCOUNTING</ng-template>
|
||||||
|
|
||||||
|
<mifosx-share-product-accounting-step
|
||||||
|
[shareProductsTemplate]="shareProductsTemplate"
|
||||||
|
[accountingRuleData]="accountingRuleData"
|
||||||
|
[shareProductFormValid]="shareProductFormValid"
|
||||||
|
>
|
||||||
|
</mifosx-share-product-accounting-step>
|
||||||
|
|
||||||
|
</mat-step>
|
||||||
|
|
||||||
|
<mat-step state="preview" *ngIf="shareProductFormValid" completed>
|
||||||
|
|
||||||
|
<ng-template matStepLabel>PREVIEW</ng-template>
|
||||||
|
|
||||||
|
<mifosx-share-product-preview-step
|
||||||
|
[shareProductsTemplate]="shareProductsTemplate"
|
||||||
|
[accountingRuleData]="accountingRuleData"
|
||||||
|
[shareProduct]="shareProduct"
|
||||||
|
(submit)="submit()"
|
||||||
|
>
|
||||||
|
</mifosx-share-product-preview-step>
|
||||||
|
|
||||||
|
</mat-step>
|
||||||
|
|
||||||
|
</mat-horizontal-stepper>
|
||||||
|
|
||||||
|
</div>
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { CreateShareProductComponent } from './create-share-product.component';
|
||||||
|
|
||||||
|
describe('CreateShareProductComponent', () => {
|
||||||
|
let component: CreateShareProductComponent;
|
||||||
|
let fixture: ComponentFixture<CreateShareProductComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ CreateShareProductComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(CreateShareProductComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
+103
@@ -0,0 +1,103 @@
|
|||||||
|
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||||
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
|
|
||||||
|
import { ShareProductDetailsStepComponent } from '../share-product-stepper/share-product-details-step/share-product-details-step.component';
|
||||||
|
import { ShareProductCurrencyStepComponent } from '../share-product-stepper/share-product-currency-step/share-product-currency-step.component';
|
||||||
|
import { ShareProductTermsStepComponent } from '../share-product-stepper/share-product-terms-step/share-product-terms-step.component';
|
||||||
|
import { ShareProductSettingsStepComponent } from '../share-product-stepper/share-product-settings-step/share-product-settings-step.component';
|
||||||
|
import { ShareProductMarketPriceStepComponent } from '../share-product-stepper/share-product-market-price-step/share-product-market-price-step.component';
|
||||||
|
import { ShareProductChargesStepComponent } from '../share-product-stepper/share-product-charges-step/share-product-charges-step.component';
|
||||||
|
import { ShareProductAccountingStepComponent } from '../share-product-stepper/share-product-accounting-step/share-product-accounting-step.component';
|
||||||
|
|
||||||
|
import { ProductsService } from 'app/products/products.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'mifosx-create-share-product',
|
||||||
|
templateUrl: './create-share-product.component.html',
|
||||||
|
styleUrls: ['./create-share-product.component.scss']
|
||||||
|
})
|
||||||
|
export class CreateShareProductComponent implements OnInit {
|
||||||
|
|
||||||
|
@ViewChild(ShareProductDetailsStepComponent) shareProductDetailsStep: ShareProductDetailsStepComponent;
|
||||||
|
@ViewChild(ShareProductCurrencyStepComponent) shareProductCurrencyStep: ShareProductCurrencyStepComponent;
|
||||||
|
@ViewChild(ShareProductTermsStepComponent) shareProductTermsStep: ShareProductTermsStepComponent;
|
||||||
|
@ViewChild(ShareProductSettingsStepComponent) shareProductSettingsStep: ShareProductSettingsStepComponent;
|
||||||
|
@ViewChild(ShareProductMarketPriceStepComponent) shareProductMarketPriceStep: ShareProductMarketPriceStepComponent;
|
||||||
|
@ViewChild(ShareProductChargesStepComponent) shareProductChargesStep: ShareProductChargesStepComponent;
|
||||||
|
@ViewChild(ShareProductAccountingStepComponent) shareProductAccountingStep: ShareProductAccountingStepComponent;
|
||||||
|
|
||||||
|
shareProductsTemplate: any;
|
||||||
|
accountingRuleData = ['None', 'Cash'];
|
||||||
|
|
||||||
|
constructor(private route: ActivatedRoute,
|
||||||
|
private productsService: ProductsService,
|
||||||
|
private router: Router) {
|
||||||
|
this.route.data.subscribe((data: { shareProductsTemplate: any }) => {
|
||||||
|
this.shareProductsTemplate = data.shareProductsTemplate;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
get shareProductDetailsForm() {
|
||||||
|
return this.shareProductDetailsStep.shareProductDetailsForm;
|
||||||
|
}
|
||||||
|
|
||||||
|
get shareProductCurrencyForm() {
|
||||||
|
return this.shareProductCurrencyStep.shareProductCurrencyForm;
|
||||||
|
}
|
||||||
|
|
||||||
|
get shareProductTermsForm() {
|
||||||
|
return this.shareProductTermsStep.shareProductTermsForm;
|
||||||
|
}
|
||||||
|
|
||||||
|
get shareProductSettingsForm() {
|
||||||
|
return this.shareProductSettingsStep.shareProductSettingsForm;
|
||||||
|
}
|
||||||
|
|
||||||
|
get shareProductMarketPriceForm() {
|
||||||
|
return this.shareProductMarketPriceStep.shareProductMarketPriceForm;
|
||||||
|
}
|
||||||
|
|
||||||
|
get shareProductAccountingForm() {
|
||||||
|
return this.shareProductAccountingStep.shareProductAccountingForm;
|
||||||
|
}
|
||||||
|
|
||||||
|
get shareProductFormValid() {
|
||||||
|
return (
|
||||||
|
this.shareProductDetailsForm.valid &&
|
||||||
|
this.shareProductCurrencyForm.valid &&
|
||||||
|
this.shareProductTermsForm.valid &&
|
||||||
|
this.shareProductSettingsForm.valid &&
|
||||||
|
this.shareProductMarketPriceForm.valid &&
|
||||||
|
this.shareProductAccountingForm.valid
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
get shareProduct() {
|
||||||
|
return {
|
||||||
|
...this.shareProductDetailsStep.shareProductDetails,
|
||||||
|
...this.shareProductCurrencyStep.shareProductCurrency,
|
||||||
|
...this.shareProductTermsStep.shareProductTerms,
|
||||||
|
...this.shareProductSettingsStep.shareProductSettings,
|
||||||
|
...this.shareProductMarketPriceStep.shareProductMarketPrice,
|
||||||
|
...this.shareProductChargesStep.shareProductCharges,
|
||||||
|
...this.shareProductAccountingStep.shareProductAccounting
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
submit() {
|
||||||
|
// TODO: Update once language and date settings are setup
|
||||||
|
const shareProduct = {
|
||||||
|
...this.shareProduct,
|
||||||
|
chargesSelected: this.shareProduct.chargesSelected.map((charge: any) => ({ id: charge.id })),
|
||||||
|
locale: 'en' // locale required for digitsAfterDecimal
|
||||||
|
};
|
||||||
|
this.productsService.createShareProduct(shareProduct)
|
||||||
|
.subscribe((response: any) => {
|
||||||
|
this.router.navigate(['../', response.resourceId], { relativeTo: this.route });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+92
@@ -0,0 +1,92 @@
|
|||||||
|
<form [formGroup]="shareProductAccountingForm">
|
||||||
|
|
||||||
|
<div fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column">
|
||||||
|
|
||||||
|
<mat-radio-group fxFlex="98%" fxLayout="row" fxLayoutGap="5%" fxLayout.lt-md="column" formControlName="accountingRule">
|
||||||
|
<mat-radio-button *ngFor="let accountingRule of accountingRuleData; let i = index" [value]="i+1">
|
||||||
|
{{ accountingRule }}
|
||||||
|
</mat-radio-button>
|
||||||
|
</mat-radio-group>
|
||||||
|
|
||||||
|
<mat-divider fxFlex="98%"></mat-divider>
|
||||||
|
|
||||||
|
<div *ngIf="shareProductAccountingForm.value.accountingRule === 2" fxFlexFill fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column">
|
||||||
|
|
||||||
|
<h4 fxFlex="98%" class="mat-h4">Assets</h4>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Share reference</mat-label>
|
||||||
|
<mat-select formControlName="shareReferenceId" required>
|
||||||
|
<mat-option *ngFor="let assetAccount of assetAccountData" [value]="assetAccount.id">
|
||||||
|
{{ assetAccount.name }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
<mat-error>
|
||||||
|
Share reference is <strong>required</strong>
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-divider fxFlex="98%"></mat-divider>
|
||||||
|
|
||||||
|
<h4 fxFlex="98%" class="mat-h4">Liabilities</h4>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Share suspense control</mat-label>
|
||||||
|
<mat-select formControlName="shareSuspenseId" required>
|
||||||
|
<mat-option *ngFor="let liabilityAccount of liabilityAccountData" [value]="liabilityAccount.id">
|
||||||
|
{{ liabilityAccount.name }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
<mat-error>
|
||||||
|
Share suspense control is <strong>required</strong>
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-divider fxFlex="98%"></mat-divider>
|
||||||
|
|
||||||
|
<h4 fxFlex="98%" class="mat-h4">Share Equity</h4>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Equity</mat-label>
|
||||||
|
<mat-select formControlName="shareEquityId" required>
|
||||||
|
<mat-option *ngFor="let equityAccount of equityAccountData" [value]="equityAccount.id">
|
||||||
|
{{ equityAccount.name }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
<mat-error>
|
||||||
|
Equity is <strong>required</strong>
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-divider fxFlex="98%"></mat-divider>
|
||||||
|
|
||||||
|
<h4 fxFlex="98%" class="mat-h4">Income</h4>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Income from fees</mat-label>
|
||||||
|
<mat-select formControlName="incomeFromFeeAccountId" required>
|
||||||
|
<mat-option *ngFor="let incomeAccount of incomeAccountData" [value]="incomeAccount.id">
|
||||||
|
{{ incomeAccount.name }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
<mat-error>
|
||||||
|
Income from fees is <strong>required</strong>
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxLayout="row" class="margin-t" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="2%">
|
||||||
|
<button mat-raised-button matStepperPrevious>
|
||||||
|
<fa-icon icon="arrow-left"></fa-icon>
|
||||||
|
Previous
|
||||||
|
</button>
|
||||||
|
<button mat-raised-button matStepperNext [disabled]="!shareProductFormValid">
|
||||||
|
Next
|
||||||
|
<fa-icon icon="arrow-right"></fa-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
h4 {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat-radio-group, h4 {
|
||||||
|
margin: 1em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat-divider {
|
||||||
|
margin: 1em 0 2em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-t {
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ShareProductAccountingStepComponent } from './share-product-accounting-step.component';
|
||||||
|
|
||||||
|
describe('ShareProductAccountingStepComponent', () => {
|
||||||
|
let component: ShareProductAccountingStepComponent;
|
||||||
|
let fixture: ComponentFixture<ShareProductAccountingStepComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ ShareProductAccountingStepComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ShareProductAccountingStepComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
+61
@@ -0,0 +1,61 @@
|
|||||||
|
import { Component, OnInit, Input } from '@angular/core';
|
||||||
|
import { FormGroup, FormBuilder, Validators, FormControl } from '@angular/forms';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'mifosx-share-product-accounting-step',
|
||||||
|
templateUrl: './share-product-accounting-step.component.html',
|
||||||
|
styleUrls: ['./share-product-accounting-step.component.scss']
|
||||||
|
})
|
||||||
|
export class ShareProductAccountingStepComponent implements OnInit {
|
||||||
|
|
||||||
|
@Input() shareProductsTemplate: any;
|
||||||
|
@Input() accountingRuleData: any;
|
||||||
|
@Input() shareProductFormValid: boolean;
|
||||||
|
|
||||||
|
shareProductAccountingForm: FormGroup;
|
||||||
|
|
||||||
|
assetAccountData: any;
|
||||||
|
incomeAccountData: any;
|
||||||
|
equityAccountData: any;
|
||||||
|
liabilityAccountData: any;
|
||||||
|
|
||||||
|
constructor(private formBuilder: FormBuilder) {
|
||||||
|
this.createShareProductAccountingForm();
|
||||||
|
this.setConditionalControls();
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.assetAccountData = this.shareProductsTemplate.accountingMappingOptions.assetAccountOptions || [];
|
||||||
|
this.incomeAccountData = this.shareProductsTemplate.accountingMappingOptions.incomeAccountOptions || [];
|
||||||
|
this.equityAccountData = this.shareProductsTemplate.accountingMappingOptions.equityAccountOptions || [];
|
||||||
|
this.liabilityAccountData = this.shareProductsTemplate.accountingMappingOptions.liabilityAccountOptions || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
createShareProductAccountingForm() {
|
||||||
|
this.shareProductAccountingForm = this.formBuilder.group({
|
||||||
|
'accountingRule': [1]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
setConditionalControls() {
|
||||||
|
this.shareProductAccountingForm.get('accountingRule').valueChanges
|
||||||
|
.subscribe((accountingRule: any) => {
|
||||||
|
if (accountingRule === 2) {
|
||||||
|
this.shareProductAccountingForm.addControl('shareReferenceId', new FormControl('', Validators.required));
|
||||||
|
this.shareProductAccountingForm.addControl('shareSuspenseId', new FormControl('', Validators.required));
|
||||||
|
this.shareProductAccountingForm.addControl('shareEquityId', new FormControl('', Validators.required));
|
||||||
|
this.shareProductAccountingForm.addControl('incomeFromFeeAccountId', new FormControl('', Validators.required));
|
||||||
|
} else {
|
||||||
|
this.shareProductAccountingForm.removeControl('shareReferenceId');
|
||||||
|
this.shareProductAccountingForm.removeControl('shareSuspenseId');
|
||||||
|
this.shareProductAccountingForm.removeControl('shareEquityId');
|
||||||
|
this.shareProductAccountingForm.removeControl('incomeFromFeeAccountId');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get shareProductAccounting() {
|
||||||
|
return this.shareProductAccountingForm.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+74
@@ -0,0 +1,74 @@
|
|||||||
|
<div fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column">
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Charge</mat-label>
|
||||||
|
<mat-select #charge>
|
||||||
|
<mat-option *ngFor="let charge of chargeData | chargesFilter:chargesDataSource:currencyCode.value" [value]="charge">
|
||||||
|
{{ charge.name }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<div fxFlex="48%" fxFlexAlign="center">
|
||||||
|
<button type="button" mat-raised-button color="primary" (click)="addCharge(charge)" [disabled]="!charge.value">
|
||||||
|
<fa-icon icon="plus"></fa-icon>
|
||||||
|
Add
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table fxFlex="98%" class="mat-elevation-z1" mat-table [dataSource]="chargesDataSource" [hidden]="chargesDataSource.length === 0">
|
||||||
|
|
||||||
|
<ng-container matColumnDef="name">
|
||||||
|
<th mat-header-cell *matHeaderCellDef> Name </th>
|
||||||
|
<td mat-cell *matCellDef="let charge">
|
||||||
|
{{ charge.name + ', ' + charge.currency.displaySymbol }}
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="chargeCalculationType">
|
||||||
|
<th mat-header-cell *matHeaderCellDef> Type </th>
|
||||||
|
<td mat-cell *matCellDef="let charge">
|
||||||
|
{{ charge.chargeCalculationType.value }}
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="amount">
|
||||||
|
<th mat-header-cell *matHeaderCellDef> Amount </th>
|
||||||
|
<td mat-cell *matCellDef="let charge">
|
||||||
|
{{ charge.amount }}
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="chargeTimeType">
|
||||||
|
<th mat-header-cell *matHeaderCellDef> Collected On </th>
|
||||||
|
<td mat-cell *matCellDef="let charge">
|
||||||
|
{{ charge.chargeTimeType.value }}
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="action">
|
||||||
|
<th mat-header-cell *matHeaderCellDef> Actions </th>
|
||||||
|
<td mat-cell *matCellDef="let charge">
|
||||||
|
<button mat-icon-button color="warn" (click)="deleteCharge(charge)">
|
||||||
|
<fa-icon icon="trash"></fa-icon>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||||
|
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||||
|
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxLayout="row" class="margin-t" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="2%">
|
||||||
|
<button mat-raised-button matStepperPrevious>
|
||||||
|
<fa-icon icon="arrow-left"></fa-icon>
|
||||||
|
Previous
|
||||||
|
</button>
|
||||||
|
<button mat-raised-button matStepperNext>
|
||||||
|
Next
|
||||||
|
<fa-icon icon="arrow-right"></fa-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-elevation-z1 {
|
||||||
|
margin: 1em 0 1.5em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-t {
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ShareProductChargesStepComponent } from './share-product-charges-step.component';
|
||||||
|
|
||||||
|
describe('ShareProductChargesStepComponent', () => {
|
||||||
|
let component: ShareProductChargesStepComponent;
|
||||||
|
let fixture: ComponentFixture<ShareProductChargesStepComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ ShareProductChargesStepComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ShareProductChargesStepComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
+56
@@ -0,0 +1,56 @@
|
|||||||
|
import { Component, OnInit, Input } from '@angular/core';
|
||||||
|
import { MatDialog } from '@angular/material';
|
||||||
|
import { FormControl } from '@angular/forms';
|
||||||
|
|
||||||
|
import { DeleteDialogComponent } from 'app/shared/delete-dialog/delete-dialog.component';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'mifosx-share-product-charges-step',
|
||||||
|
templateUrl: './share-product-charges-step.component.html',
|
||||||
|
styleUrls: ['./share-product-charges-step.component.scss']
|
||||||
|
})
|
||||||
|
export class ShareProductChargesStepComponent implements OnInit {
|
||||||
|
|
||||||
|
@Input() shareProductsTemplate: any;
|
||||||
|
@Input() currencyCode: FormControl;
|
||||||
|
|
||||||
|
chargeData: any;
|
||||||
|
|
||||||
|
chargesDataSource: {}[];
|
||||||
|
displayedColumns: string[] = ['name', 'chargeCalculationType', 'amount', 'chargeTimeType', 'action'];
|
||||||
|
|
||||||
|
constructor(public dialog: MatDialog) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.chargeData = this.shareProductsTemplate.chargeOptions;
|
||||||
|
|
||||||
|
this.chargesDataSource = [];
|
||||||
|
|
||||||
|
this.currencyCode.valueChanges.subscribe(() => this.chargesDataSource = []);
|
||||||
|
}
|
||||||
|
|
||||||
|
addCharge(charge: any) {
|
||||||
|
this.chargesDataSource = this.chargesDataSource.concat([charge.value]);
|
||||||
|
charge.value = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteCharge(charge: any) {
|
||||||
|
const deleteChargeDialogRef = this.dialog.open(DeleteDialogComponent, {
|
||||||
|
data: { deleteContext: `charge ${charge.name}` }
|
||||||
|
});
|
||||||
|
deleteChargeDialogRef.afterClosed().subscribe((response: any) => {
|
||||||
|
if (response.delete) {
|
||||||
|
this.chargesDataSource.splice(this.chargesDataSource.indexOf(charge), 1);
|
||||||
|
this.chargesDataSource = this.chargesDataSource.concat([]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get shareProductCharges() {
|
||||||
|
return {
|
||||||
|
chargesSelected: this.chargesDataSource
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+46
@@ -0,0 +1,46 @@
|
|||||||
|
<form [formGroup]="shareProductCurrencyForm">
|
||||||
|
|
||||||
|
<div fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column">
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Currency</mat-label>
|
||||||
|
<mat-select formControlName="currencyCode" required>
|
||||||
|
<mat-option *ngFor="let currency of currencyData" [value]="currency.code">
|
||||||
|
{{ currency.name }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
<mat-error>
|
||||||
|
Currency is <strong>required</strong>
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Decimal Places</mat-label>
|
||||||
|
<input type="number" matInput formControlName="digitsAfterDecimal" required>
|
||||||
|
<mat-error>
|
||||||
|
Decimal Places is <strong>required</strong>
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Currency in multiples of</mat-label>
|
||||||
|
<input type="number" matInput formControlName="inMultiplesOf" required>
|
||||||
|
<mat-error>
|
||||||
|
Currency in multiples of is <strong>required</strong>
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxLayout="row" class="margin-t" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="2%">
|
||||||
|
<button mat-raised-button matStepperPrevious>
|
||||||
|
<fa-icon icon="arrow-left"></fa-icon>
|
||||||
|
Previous
|
||||||
|
</button>
|
||||||
|
<button mat-raised-button matStepperNext>
|
||||||
|
Next
|
||||||
|
<fa-icon icon="arrow-right"></fa-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
.margin-t {
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ShareProductCurrencyStepComponent } from './share-product-currency-step.component';
|
||||||
|
|
||||||
|
describe('ShareProductCurrencyStepComponent', () => {
|
||||||
|
let component: ShareProductCurrencyStepComponent;
|
||||||
|
let fixture: ComponentFixture<ShareProductCurrencyStepComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ ShareProductCurrencyStepComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ShareProductCurrencyStepComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
+42
@@ -0,0 +1,42 @@
|
|||||||
|
import { Component, OnInit, Input } from '@angular/core';
|
||||||
|
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'mifosx-share-product-currency-step',
|
||||||
|
templateUrl: './share-product-currency-step.component.html',
|
||||||
|
styleUrls: ['./share-product-currency-step.component.scss']
|
||||||
|
})
|
||||||
|
export class ShareProductCurrencyStepComponent implements OnInit {
|
||||||
|
|
||||||
|
@Input() shareProductsTemplate: any;
|
||||||
|
|
||||||
|
shareProductCurrencyForm: FormGroup;
|
||||||
|
|
||||||
|
currencyData: any;
|
||||||
|
|
||||||
|
constructor(private formBuilder: FormBuilder) {
|
||||||
|
this.createShareProductCurrencyForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.currencyData = this.shareProductsTemplate.currencyOptions;
|
||||||
|
|
||||||
|
this.shareProductCurrencyForm.patchValue({
|
||||||
|
'currencyCode': this.currencyData[0].code,
|
||||||
|
'digitsAfterDecimal': 2
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
createShareProductCurrencyForm() {
|
||||||
|
this.shareProductCurrencyForm = this.formBuilder.group({
|
||||||
|
'currencyCode': ['', Validators.required],
|
||||||
|
'digitsAfterDecimal': ['', Validators.required],
|
||||||
|
'inMultiplesOf': ['', Validators.required]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get shareProductCurrency() {
|
||||||
|
return this.shareProductCurrencyForm.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
<form [formGroup]="shareProductDetailsForm">
|
||||||
|
|
||||||
|
<div fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column">
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Product Name</mat-label>
|
||||||
|
<input matInput formControlName="name" required>
|
||||||
|
<mat-error>
|
||||||
|
Product Name is <strong>required</strong>
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Short Name</mat-label>
|
||||||
|
<input matInput formControlName="shortName" maxlength="4" required>
|
||||||
|
<mat-error>
|
||||||
|
Short Name is <strong>required</strong>
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="98%">
|
||||||
|
<mat-label>Description</mat-label>
|
||||||
|
<textarea matInput formControlName="description"></textarea>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxLayout="row" class="margin-t" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="2%">
|
||||||
|
<button mat-raised-button matStepperPrevious disabled>
|
||||||
|
<fa-icon icon="arrow-left"></fa-icon>
|
||||||
|
Previous
|
||||||
|
</button>
|
||||||
|
<button mat-raised-button matStepperNext>
|
||||||
|
Next
|
||||||
|
<fa-icon icon="arrow-right"></fa-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
.margin-t {
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ShareProductDetailsStepComponent } from './share-product-details-step.component';
|
||||||
|
|
||||||
|
describe('ShareProductDetailsStepComponent', () => {
|
||||||
|
let component: ShareProductDetailsStepComponent;
|
||||||
|
let fixture: ComponentFixture<ShareProductDetailsStepComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ ShareProductDetailsStepComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ShareProductDetailsStepComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'mifosx-share-product-details-step',
|
||||||
|
templateUrl: './share-product-details-step.component.html',
|
||||||
|
styleUrls: ['./share-product-details-step.component.scss']
|
||||||
|
})
|
||||||
|
export class ShareProductDetailsStepComponent implements OnInit {
|
||||||
|
|
||||||
|
shareProductDetailsForm: FormGroup;
|
||||||
|
|
||||||
|
constructor(private formBuilder: FormBuilder) {
|
||||||
|
this.createShareProductDetailsForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
createShareProductDetailsForm() {
|
||||||
|
this.shareProductDetailsForm = this.formBuilder.group({
|
||||||
|
'name': ['', Validators.required],
|
||||||
|
'shortName': ['', Validators.required],
|
||||||
|
'description': ['']
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get shareProductDetails() {
|
||||||
|
return this.shareProductDetailsForm.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+56
@@ -0,0 +1,56 @@
|
|||||||
|
<div fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column">
|
||||||
|
|
||||||
|
<h4 fxFlex="23%" class="mat-h4">Market Price Periods</h4>
|
||||||
|
|
||||||
|
<div fxFlex="73%">
|
||||||
|
<button type="button" mat-raised-button color="primary" (click)="addMarketPricePeriod()">
|
||||||
|
<fa-icon icon="plus"></fa-icon>
|
||||||
|
Add
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table fxFlex="98%" class="mat-elevation-z1" mat-table [dataSource]="marketPricePeriods.value" *ngIf="marketPricePeriods.value.length">
|
||||||
|
|
||||||
|
<ng-container matColumnDef="fromDate">
|
||||||
|
<th mat-header-cell *matHeaderCellDef> From Date </th>
|
||||||
|
<td mat-cell *matCellDef="let marketPricePeriod">
|
||||||
|
{{ marketPricePeriod.fromDate | date }}
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="shareValue">
|
||||||
|
<th mat-header-cell *matHeaderCellDef> Nominal/Unit Price </th>
|
||||||
|
<td mat-cell *matCellDef="let marketPricePeriod">
|
||||||
|
{{ marketPricePeriod.shareValue }}
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="actions">
|
||||||
|
<th mat-header-cell *matHeaderCellDef> Actions </th>
|
||||||
|
<td mat-cell *matCellDef="let variation; let i = index">
|
||||||
|
<button mat-icon-button color="primary" (click)="editMarketPricePeriod(i)">
|
||||||
|
<fa-icon icon="edit"></fa-icon>
|
||||||
|
</button>
|
||||||
|
<button mat-icon-button color="warn" (click)="deleteMarketPricePeriod(i)">
|
||||||
|
<fa-icon icon="trash"></fa-icon>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||||
|
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||||
|
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxLayout="row" class="margin-t" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="2%">
|
||||||
|
<button mat-raised-button matStepperPrevious>
|
||||||
|
<fa-icon icon="arrow-left"></fa-icon>
|
||||||
|
Previous
|
||||||
|
</button>
|
||||||
|
<button mat-raised-button matStepperNext>
|
||||||
|
Next
|
||||||
|
<fa-icon icon="arrow-right"></fa-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-elevation-z1 {
|
||||||
|
margin: 1em 0 1.5em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-weight: 500;
|
||||||
|
margin: 1em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-t {
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ShareProductMarketPriceStepComponent } from './share-product-market-price-step.component';
|
||||||
|
|
||||||
|
describe('ShareProductMarketPriceStepComponent', () => {
|
||||||
|
let component: ShareProductMarketPriceStepComponent;
|
||||||
|
let fixture: ComponentFixture<ShareProductMarketPriceStepComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ ShareProductMarketPriceStepComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ShareProductMarketPriceStepComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
+115
@@ -0,0 +1,115 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { DatePipe } from '@angular/common';
|
||||||
|
import { FormGroup, FormBuilder, FormArray } from '@angular/forms';
|
||||||
|
import { MatDialog } from '@angular/material';
|
||||||
|
|
||||||
|
import { FormDialogComponent } from 'app/shared/form-dialog/form-dialog.component';
|
||||||
|
import { DeleteDialogComponent } from 'app/shared/delete-dialog/delete-dialog.component';
|
||||||
|
|
||||||
|
import { FormfieldBase } from 'app/shared/form-dialog/formfield/model/formfield-base';
|
||||||
|
import { DatepickerBase } from 'app/shared/form-dialog/formfield/model/datepicker-base';
|
||||||
|
import { InputBase } from 'app/shared/form-dialog/formfield/model/input-base';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'mifosx-share-product-market-price-step',
|
||||||
|
templateUrl: './share-product-market-price-step.component.html',
|
||||||
|
styleUrls: ['./share-product-market-price-step.component.scss']
|
||||||
|
})
|
||||||
|
export class ShareProductMarketPriceStepComponent implements OnInit {
|
||||||
|
|
||||||
|
shareProductMarketPriceForm: FormGroup;
|
||||||
|
|
||||||
|
displayedColumns: string[] = ['fromDate', 'shareValue', 'actions'];
|
||||||
|
|
||||||
|
constructor(private formBuilder: FormBuilder,
|
||||||
|
public dialog: MatDialog,
|
||||||
|
private datePipe: DatePipe) {
|
||||||
|
this.createShareProductMarketPriceForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
createShareProductMarketPriceForm() {
|
||||||
|
this.shareProductMarketPriceForm = this.formBuilder.group({
|
||||||
|
'marketPricePeriods': this.formBuilder.array([])
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get marketPricePeriods(): FormArray {
|
||||||
|
return this.shareProductMarketPriceForm.get('marketPricePeriods') as FormArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
addMarketPricePeriod() {
|
||||||
|
const data = this.getData();
|
||||||
|
const addVariationsForBorrowerCycleDialogRef = this.dialog.open(FormDialogComponent, { data });
|
||||||
|
addVariationsForBorrowerCycleDialogRef.afterClosed().subscribe((response: any) => {
|
||||||
|
if (response.data) {
|
||||||
|
this.marketPricePeriods.push(response.data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
editMarketPricePeriod(index: number) {
|
||||||
|
const data = { ...this.getData(this.marketPricePeriods.at(index).value), layout: { addButtonText: 'Edit' } };
|
||||||
|
const addVariationsForBorrowerCycleDialogRef = this.dialog.open(FormDialogComponent, { data });
|
||||||
|
addVariationsForBorrowerCycleDialogRef.afterClosed().subscribe((response: any) => {
|
||||||
|
if (response.data) {
|
||||||
|
this.marketPricePeriods.at(index).patchValue(response.data.value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteMarketPricePeriod(index: number) {
|
||||||
|
const deleteVariationsForBorrowerCycleDialogRef = this.dialog.open(DeleteDialogComponent, {
|
||||||
|
data: { deleteContext: `this` }
|
||||||
|
});
|
||||||
|
deleteVariationsForBorrowerCycleDialogRef.afterClosed().subscribe((response: any) => {
|
||||||
|
if (response.delete) {
|
||||||
|
this.marketPricePeriods.removeAt(index);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getData(values?: any) {
|
||||||
|
return { title: 'Market Price Period', formfields: this.getFormfields(values) };
|
||||||
|
}
|
||||||
|
|
||||||
|
getFormfields(values?: any) {
|
||||||
|
const formfields: FormfieldBase[] = [
|
||||||
|
new DatepickerBase({
|
||||||
|
controlName: 'fromDate',
|
||||||
|
label: 'From Date',
|
||||||
|
value: values ? values.fromDate : undefined,
|
||||||
|
maxDate: new Date(new Date().setFullYear(new Date().getFullYear() + 10)),
|
||||||
|
required: true,
|
||||||
|
order: 1
|
||||||
|
}),
|
||||||
|
new InputBase({
|
||||||
|
controlName: 'shareValue',
|
||||||
|
label: 'Nominal/Unit Price',
|
||||||
|
value: values ? values.shareValue : undefined,
|
||||||
|
type: 'number',
|
||||||
|
required: true,
|
||||||
|
order: 2
|
||||||
|
})
|
||||||
|
];
|
||||||
|
return formfields;
|
||||||
|
}
|
||||||
|
|
||||||
|
get shareProductMarketPrice() {
|
||||||
|
// TODO: Update once language and date settings are setup
|
||||||
|
const dateFormat = 'yyyy-MM-dd';
|
||||||
|
const marketPricePeriods = [];
|
||||||
|
for (const marketPricePeriod of this.marketPricePeriods.value) {
|
||||||
|
marketPricePeriods.push({
|
||||||
|
...marketPricePeriod,
|
||||||
|
fromDate: this.datePipe.transform(marketPricePeriod.fromDate, dateFormat),
|
||||||
|
dateFormat,
|
||||||
|
locale: 'en'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return { marketPricePeriods };
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+214
@@ -0,0 +1,214 @@
|
|||||||
|
<div fxLayout="row wrap" fxLayout.lt-md="column">
|
||||||
|
|
||||||
|
<h2 class="mat-h2" fxFlexFill>{{ shareProduct.name }}</h2>
|
||||||
|
|
||||||
|
<mat-divider fxFlexFill></mat-divider>
|
||||||
|
|
||||||
|
<h3 class="mat-h3" fxFlexFill>Details</h3>
|
||||||
|
|
||||||
|
<mat-divider fxFlexFill></mat-divider>
|
||||||
|
|
||||||
|
<div fxFlexFill>
|
||||||
|
<span fxFlex="40%">Short Name:</span>
|
||||||
|
<span fxFlex="60%">{{ shareProduct.shortName }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxFlexFill *ngIf="shareProduct.description">
|
||||||
|
<span fxFlex="40%">Description:</span>
|
||||||
|
<span fxFlex="60%">{{ shareProduct.description }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3 class="mat-h3" fxFlexFill>Currency</h3>
|
||||||
|
|
||||||
|
<mat-divider fxFlexFill></mat-divider>
|
||||||
|
|
||||||
|
<div fxFlexFill>
|
||||||
|
<span fxFlex="40%">Currency:</span>
|
||||||
|
<span fxFlex="60%">{{ shareProduct.currencyCode | find:shareProductsTemplate.currencyOptions:'code':'name' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxFlexFill>
|
||||||
|
<span fxFlex="40%">Decimal Places:</span>
|
||||||
|
<span fxFlex="60%">{{ shareProduct.digitsAfterDecimal }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxFlexFill>
|
||||||
|
<span fxFlex="40%">Currency in multiples of:</span>
|
||||||
|
<span fxFlex="60%">{{ shareProduct.inMultiplesOf }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3 class="mat-h3" fxFlexFill>Terms</h3>
|
||||||
|
|
||||||
|
<mat-divider fxFlexFill></mat-divider>
|
||||||
|
|
||||||
|
<div fxFlexFill>
|
||||||
|
<span fxFlex="40%">Total Number of Shares:</span>
|
||||||
|
<span fxFlex="60%">{{ shareProduct.totalShares }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxFlexFill>
|
||||||
|
<span fxFlex="40%">Shares to be Issued:</span>
|
||||||
|
<span fxFlex="60%">{{ shareProduct.sharesIssued }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxFlexFill>
|
||||||
|
<span fxFlex="40%">Nominal/Unit Price:</span>
|
||||||
|
<span fxFlex="60%">{{ shareProduct.unitPrice }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxFlexFill>
|
||||||
|
<span fxFlex="40%">Capital Value:</span>
|
||||||
|
<span fxFlex="60%">{{ shareProduct.shareCapital }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3 class="mat-h3" fxFlexFill>Settings</h3>
|
||||||
|
|
||||||
|
<mat-divider fxFlexFill></mat-divider>
|
||||||
|
|
||||||
|
<div fxFlexFill>
|
||||||
|
<span fxFlex="40%">Shares per Client:</span>
|
||||||
|
<span fxFlex="60%">{{ shareProduct.nominalShares + ' (Min: ' + (shareProduct.minimumShares ? shareProduct.minimumShares : shareProduct.nominalShares) + ', Max: ' + (shareProduct.maximumShares ? shareProduct.maximumShares : shareProduct.nominalShares) + ')' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxFlexFill *ngIf="shareProduct.minimumActivePeriodForDividends">
|
||||||
|
<span fxFlex="40%">Minimum Active Period:</span>
|
||||||
|
<span fxFlex="60%">{{ shareProduct.minimumActivePeriodForDividends + ' ' + (shareProduct.minimumactiveperiodFrequencyType | find:shareProductsTemplate.minimumActivePeriodFrequencyTypeOptions:'id':'value') }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxFlexFill *ngIf="shareProduct.lockinPeriodFrequency">
|
||||||
|
<span fxFlex="40%">Lock-in Period:</span>
|
||||||
|
<span fxFlex="60%">{{ shareProduct.lockinPeriodFrequency + ' ' + (shareProduct.lockinPeriodFrequencyType | find:shareProductsTemplate.lockinPeriodFrequencyTypeOptions:'id':'value') }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxFlexFill>
|
||||||
|
<span fxFlex="40%">Allow dividends for inactive clients:</span>
|
||||||
|
<span fxFlex="60%">{{ shareProduct.allowDividendCalculationForInactiveClients ? 'Yes' : 'No' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxFlexFill *ngIf="shareProduct.marketPricePeriods.length" fxLayout="row wrap" fxLayout.lt-md="column">
|
||||||
|
|
||||||
|
<h3 class="mat-h3" fxFlexFill>Market Price Periods</h3>
|
||||||
|
|
||||||
|
<mat-divider fxFlexFill></mat-divider>
|
||||||
|
|
||||||
|
<table fxFlexFill class="mat-elevation-z1" mat-table [dataSource]="shareProduct.marketPricePeriods">
|
||||||
|
|
||||||
|
<ng-container matColumnDef="fromDate">
|
||||||
|
<th mat-header-cell *matHeaderCellDef> From Date </th>
|
||||||
|
<td mat-cell *matCellDef="let marketPricePeriod">
|
||||||
|
{{ marketPricePeriod.fromDate | date }}
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="shareValue">
|
||||||
|
<th mat-header-cell *matHeaderCellDef> Nominal/Unit Price </th>
|
||||||
|
<td mat-cell *matCellDef="let marketPricePeriod">
|
||||||
|
{{ marketPricePeriod.shareValue }}
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<tr mat-header-row *matHeaderRowDef="marketPriceDisplayedColumns"></tr>
|
||||||
|
<tr mat-row *matRowDef="let row; columns: marketPriceDisplayedColumns;"></tr>
|
||||||
|
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxFlexFill *ngIf="shareProduct.chargesSelected.length" fxLayout="row wrap" fxLayout.lt-md="column">
|
||||||
|
|
||||||
|
<h3 class="mat-h3" fxFlexFill>Charges</h3>
|
||||||
|
|
||||||
|
<mat-divider fxFlexFill></mat-divider>
|
||||||
|
|
||||||
|
<table fxFlexFill class="mat-elevation-z1" mat-table [dataSource]="shareProduct.chargesSelected">
|
||||||
|
|
||||||
|
<ng-container matColumnDef="name">
|
||||||
|
<th mat-header-cell *matHeaderCellDef> Name </th>
|
||||||
|
<td mat-cell *matCellDef="let charge">
|
||||||
|
{{ charge.name + ', ' + charge.currency.displaySymbol }}
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="chargeCalculationType">
|
||||||
|
<th mat-header-cell *matHeaderCellDef> Type </th>
|
||||||
|
<td mat-cell *matCellDef="let charge">
|
||||||
|
{{ charge.chargeCalculationType.value }}
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="amount">
|
||||||
|
<th mat-header-cell *matHeaderCellDef> Amount </th>
|
||||||
|
<td mat-cell *matCellDef="let charge">
|
||||||
|
{{ charge.amount }}
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="chargeTimeType">
|
||||||
|
<th mat-header-cell *matHeaderCellDef> Collected On </th>
|
||||||
|
<td mat-cell *matCellDef="let charge">
|
||||||
|
{{ charge.chargeTimeType.value }}
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<tr mat-header-row *matHeaderRowDef="chargesDisplayedColumns"></tr>
|
||||||
|
<tr mat-row *matRowDef="let row; columns: chargesDisplayedColumns;"></tr>
|
||||||
|
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3 class="mat-h3" fxFlexFill>Accounting</h3>
|
||||||
|
|
||||||
|
<mat-divider fxFlexFill></mat-divider>
|
||||||
|
|
||||||
|
<div fxFlexFill>
|
||||||
|
<span fxFlex="40%">Type:</span>
|
||||||
|
<span fxFlex="60%">{{ accountingRuleData[shareProduct.accountingRule-1] }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxFlexFill *ngIf="shareProduct.accountingRule === 2" fxLayout="row wrap" fxLayout.lt-md="column">
|
||||||
|
|
||||||
|
<h4 fxFlexFill class="mat-h4">Assets</h4>
|
||||||
|
|
||||||
|
<div fxFlexFill>
|
||||||
|
<span fxFlex="40%">Share reference:</span>
|
||||||
|
<span fxFlex="60%">{{ shareProduct.shareReferenceId | find:shareProductsTemplate.accountingMappingOptions.assetAccountOptions:'id':'name' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h4 fxFlexFill class="mat-h4">Liabilities</h4>
|
||||||
|
|
||||||
|
<div fxFlexFill>
|
||||||
|
<span fxFlex="40%">Share suspense control:</span>
|
||||||
|
<span fxFlex="60%">{{ shareProduct.shareSuspenseId | find:shareProductsTemplate.accountingMappingOptions.liabilityAccountOptions:'id':'name' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h4 fxFlexFill class="mat-h4">Expenses</h4>
|
||||||
|
|
||||||
|
<div fxFlexFill>
|
||||||
|
<span fxFlex="40%">Share Equity:</span>
|
||||||
|
<span fxFlex="60%">{{ shareProduct.shareEquityId | find:shareProductsTemplate.accountingMappingOptions.equityAccountOptions:'id':'name' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h4 fxFlexFill class="mat-h4">Income</h4>
|
||||||
|
|
||||||
|
<div fxFlexFill>
|
||||||
|
<span fxFlex="40%">Income from fees:</span>
|
||||||
|
<span fxFlex="60%">{{ shareProduct.incomeFromFeeAccountId | find:shareProductsTemplate.accountingMappingOptions.incomeAccountOptions:'id':'name' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxLayout="row" class="margin-t" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="2%">
|
||||||
|
<button mat-raised-button matStepperPrevious>
|
||||||
|
<fa-icon icon="arrow-left"></fa-icon>
|
||||||
|
Previous
|
||||||
|
</button>
|
||||||
|
<button mat-raised-button [routerLink]="['../']">
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
<button mat-raised-button color="primary" (click)="submit.emit()">
|
||||||
|
Submit
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-elevation-z1 {
|
||||||
|
margin: 1em 0 1.5em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2, h3, h4 {
|
||||||
|
margin: 0;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
margin: 0.5em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat-divider {
|
||||||
|
margin: 0 0 0.5em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-t {
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ShareProductPreviewStepComponent } from './share-product-preview-step.component';
|
||||||
|
|
||||||
|
describe('ShareProductPreviewStepComponent', () => {
|
||||||
|
let component: ShareProductPreviewStepComponent;
|
||||||
|
let fixture: ComponentFixture<ShareProductPreviewStepComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ ShareProductPreviewStepComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ShareProductPreviewStepComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'mifosx-share-product-preview-step',
|
||||||
|
templateUrl: './share-product-preview-step.component.html',
|
||||||
|
styleUrls: ['./share-product-preview-step.component.scss']
|
||||||
|
})
|
||||||
|
export class ShareProductPreviewStepComponent implements OnInit {
|
||||||
|
|
||||||
|
@Input() shareProductsTemplate: any;
|
||||||
|
@Input() accountingRuleData: any;
|
||||||
|
@Input() shareProduct: any;
|
||||||
|
@Output() submit = new EventEmitter();
|
||||||
|
|
||||||
|
marketPriceDisplayedColumns: string[] = ['fromDate', 'shareValue'];
|
||||||
|
chargesDisplayedColumns: string[] = ['name', 'chargeCalculationType', 'amount', 'chargeTimeType'];
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+74
@@ -0,0 +1,74 @@
|
|||||||
|
<form [formGroup]="shareProductSettingsForm">
|
||||||
|
|
||||||
|
<div fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column">
|
||||||
|
|
||||||
|
<h4 fxFlex="98%" class="mat-h4">Shares per Client</h4>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="31%">
|
||||||
|
<mat-label>Minimum</mat-label>
|
||||||
|
<input type="number" matInput formControlName="minimumShares">
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="31%">
|
||||||
|
<mat-label>Default</mat-label>
|
||||||
|
<input type="number" matInput formControlName="nominalShares" required>
|
||||||
|
<mat-error>
|
||||||
|
Default Shares per Client is <strong>required</strong>
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="31%">
|
||||||
|
<mat-label>Maximum</mat-label>
|
||||||
|
<input type="number" matInput formControlName="maximumShares">
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<h4 fxFlex="98%" class="mat-h4">Minimum Active Period</h4>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Frequency</mat-label>
|
||||||
|
<input type="number" matInput formControlName="minimumActivePeriodForDividends">
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Type</mat-label>
|
||||||
|
<mat-select formControlName="minimumactiveperiodFrequencyType">
|
||||||
|
<mat-option *ngFor="let minimumActivePeriodFrequencyType of minimumActivePeriodFrequencyTypeData" [value]="minimumActivePeriodFrequencyType.id">
|
||||||
|
{{ minimumActivePeriodFrequencyType.value }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<h4 fxFlex="98%" class="mat-h4">Lock-in Period</h4>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Frequency</mat-label>
|
||||||
|
<input type="number" matInput formControlName="lockinPeriodFrequency">
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Type</mat-label>
|
||||||
|
<mat-select formControlName="lockinPeriodFrequencyType">
|
||||||
|
<mat-option *ngFor="let lockinPeriodFrequencyType of lockinPeriodFrequencyTypeData" [value]="lockinPeriodFrequencyType.id">
|
||||||
|
{{ lockinPeriodFrequencyType.value }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-checkbox fxFlex="98%" class="margin-v" labelPosition="before" formControlName="allowDividendCalculationForInactiveClients">
|
||||||
|
Allow dividends for inactive clients
|
||||||
|
</mat-checkbox>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxLayout="row" class="margin-t" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="2%">
|
||||||
|
<button mat-raised-button matStepperPrevious>
|
||||||
|
<fa-icon icon="arrow-left"></fa-icon>
|
||||||
|
Previous
|
||||||
|
</button>
|
||||||
|
<button mat-raised-button matStepperNext>
|
||||||
|
Next
|
||||||
|
<fa-icon icon="arrow-right"></fa-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
h4 {
|
||||||
|
font-weight: 500;
|
||||||
|
margin: 1em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-t {
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-v {
|
||||||
|
margin: 1em 0;
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ShareProductSettingsStepComponent } from './share-product-settings-step.component';
|
||||||
|
|
||||||
|
describe('ShareProductSettingsStepComponent', () => {
|
||||||
|
let component: ShareProductSettingsStepComponent;
|
||||||
|
let fixture: ComponentFixture<ShareProductSettingsStepComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ ShareProductSettingsStepComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ShareProductSettingsStepComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
import { Component, OnInit, Input } from '@angular/core';
|
||||||
|
import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'mifosx-share-product-settings-step',
|
||||||
|
templateUrl: './share-product-settings-step.component.html',
|
||||||
|
styleUrls: ['./share-product-settings-step.component.scss']
|
||||||
|
})
|
||||||
|
export class ShareProductSettingsStepComponent implements OnInit {
|
||||||
|
|
||||||
|
@Input() shareProductsTemplate: any;
|
||||||
|
|
||||||
|
shareProductSettingsForm: FormGroup;
|
||||||
|
|
||||||
|
minimumActivePeriodFrequencyTypeData: any;
|
||||||
|
lockinPeriodFrequencyTypeData: any;
|
||||||
|
|
||||||
|
constructor(private formBuilder: FormBuilder) {
|
||||||
|
this.createShareProductSettingsForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.minimumActivePeriodFrequencyTypeData = this.shareProductsTemplate.minimumActivePeriodFrequencyTypeOptions;
|
||||||
|
this.lockinPeriodFrequencyTypeData = this.shareProductsTemplate.lockinPeriodFrequencyTypeOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
createShareProductSettingsForm() {
|
||||||
|
this.shareProductSettingsForm = this.formBuilder.group({
|
||||||
|
'minimumShares': [''],
|
||||||
|
'nominalShares': ['', Validators.required],
|
||||||
|
'maximumShares': [''],
|
||||||
|
'minimumActivePeriodForDividends': [''],
|
||||||
|
'minimumactiveperiodFrequencyType': [''],
|
||||||
|
'lockinPeriodFrequency': [''],
|
||||||
|
'lockinPeriodFrequencyType': [''],
|
||||||
|
'allowDividendCalculationForInactiveClients': [false]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get shareProductSettings() {
|
||||||
|
return this.shareProductSettingsForm.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+50
@@ -0,0 +1,50 @@
|
|||||||
|
<form [formGroup]="shareProductTermsForm">
|
||||||
|
|
||||||
|
<div fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column">
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Total Number of Shares</mat-label>
|
||||||
|
<input type="number" matInput formControlName="totalShares" required>
|
||||||
|
<mat-error>
|
||||||
|
Total Number of Shares is <strong>required</strong>
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Shares to be Issued</mat-label>
|
||||||
|
<input type="number" matInput formControlName="sharesIssued" required>
|
||||||
|
<mat-error>
|
||||||
|
Shares to be Issued is <strong>required</strong>
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Nominal/Unit Price</mat-label>
|
||||||
|
<input type="number" matInput formControlName="unitPrice" required>
|
||||||
|
<mat-error>
|
||||||
|
Nominal Price is <strong>required</strong>
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Capital Value</mat-label>
|
||||||
|
<input type="number" matInput formControlName="shareCapital" readonly>
|
||||||
|
<mat-hint>
|
||||||
|
Shares to be Issued * Nominal Price (Auto calculated)
|
||||||
|
</mat-hint>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxLayout="row" class="margin-t" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="2%">
|
||||||
|
<button mat-raised-button matStepperPrevious>
|
||||||
|
<fa-icon icon="arrow-left"></fa-icon>
|
||||||
|
Previous
|
||||||
|
</button>
|
||||||
|
<button mat-raised-button matStepperNext>
|
||||||
|
Next
|
||||||
|
<fa-icon icon="arrow-right"></fa-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
.margin-t {
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ShareProductTermsStepComponent } from './share-product-terms-step.component';
|
||||||
|
|
||||||
|
describe('ShareProductTermsStepComponent', () => {
|
||||||
|
let component: ShareProductTermsStepComponent;
|
||||||
|
let fixture: ComponentFixture<ShareProductTermsStepComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ ShareProductTermsStepComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ShareProductTermsStepComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
|
||||||
|
import { combineLatest } from 'rxjs';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'mifosx-share-product-terms-step',
|
||||||
|
templateUrl: './share-product-terms-step.component.html',
|
||||||
|
styleUrls: ['./share-product-terms-step.component.scss']
|
||||||
|
})
|
||||||
|
export class ShareProductTermsStepComponent implements OnInit {
|
||||||
|
|
||||||
|
shareProductTermsForm: FormGroup;
|
||||||
|
|
||||||
|
constructor(private formBuilder: FormBuilder) {
|
||||||
|
this.createShareProductTermsForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
combineLatest([
|
||||||
|
this.shareProductTermsForm.get('sharesIssued').valueChanges,
|
||||||
|
this.shareProductTermsForm.get('unitPrice').valueChanges
|
||||||
|
]).subscribe(([sharesIssued, unitPrice]: number[]) => {
|
||||||
|
this.shareProductTermsForm.get('shareCapital').setValue(sharesIssued * unitPrice);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
createShareProductTermsForm() {
|
||||||
|
this.shareProductTermsForm = this.formBuilder.group({
|
||||||
|
'totalShares': ['', Validators.required],
|
||||||
|
'sharesIssued': ['', Validators.required],
|
||||||
|
'unitPrice': ['', Validators.required],
|
||||||
|
'shareCapital': ['']
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get shareProductTerms() {
|
||||||
|
return this.shareProductTermsForm.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
/** Angular Imports */
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Resolve } from '@angular/router';
|
||||||
|
|
||||||
|
/** rxjs Imports */
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
|
||||||
|
/** Custom Services */
|
||||||
|
import { ProductsService } from '../products.service';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ShareProductsTemplateResolver implements Resolve<Object> {
|
||||||
|
|
||||||
|
constructor(private productsService: ProductsService) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the share products template data.
|
||||||
|
* @returns {Observable<any>}
|
||||||
|
*/
|
||||||
|
resolve(): Observable<any> {
|
||||||
|
return this.productsService.getShareProductsTemplate();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<div class="container m-b-20" fxLayout="row" fxLayoutAlign="end" fxLayoutGap="20px">
|
<div class="container m-b-20" fxLayout="row" fxLayoutAlign="end" fxLayoutGap="20px">
|
||||||
<button mat-raised-button color="primary">
|
<button mat-raised-button color="primary" [routerLink]="['create']">
|
||||||
<fa-icon icon="plus"></fa-icon>
|
<fa-icon icon="plus"></fa-icon>
|
||||||
Create Share Product
|
Create Share Product
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -1,35 +1,43 @@
|
|||||||
<div [formGroup]="form" fxFlexFill>
|
<div [formGroup]="form" fxFlexFill>
|
||||||
|
|
||||||
<div>
|
<div *ngIf="formfield.controlType==='input' || formfield.controlType==='select'" fxFlexFill>
|
||||||
|
|
||||||
|
<mat-form-field fxFlexFill>
|
||||||
|
|
||||||
<div *ngIf="formfield.controlType==='input'||formfield.controlType==='select'">
|
<mat-label>{{ formfield.label }}</mat-label>
|
||||||
|
|
||||||
<mat-form-field fxFlexFill>
|
|
||||||
|
|
||||||
<mat-label>{{ formfield.label }}</mat-label>
|
<input *ngIf="formfield.controlType==='input'" [type]="formfield.type" matInput
|
||||||
|
[formControlName]="formfield.controlName" [required]="formfield.required">
|
||||||
|
|
||||||
<input *ngIf="formfield.controlType==='input'" [type]="formfield.type" matInput
|
<mat-select *ngIf="formfield.controlType==='select'" [formControlName]="formfield.controlName"
|
||||||
[formControlName]="formfield.controlName" [required]="formfield.required">
|
[required]="formfield.required">
|
||||||
|
<mat-option *ngFor="let option of formfield.options.data" [value]="option[formfield.options.value]">
|
||||||
|
{{ option[formfield.options.label] }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
|
||||||
<mat-select *ngIf="formfield.controlType==='select'" [formControlName]="formfield.controlName"
|
<mat-error *ngIf="form.controls[formfield.controlName].hasError('required')">
|
||||||
[required]="formfield.required">
|
{{ formfield.label }} is <strong>required</strong>
|
||||||
<mat-option *ngFor="let option of formfield.options.data" [value]="option[formfield.options.value]">
|
</mat-error>
|
||||||
{{ option[formfield.options.label] }}
|
|
||||||
</mat-option>
|
|
||||||
</mat-select>
|
|
||||||
|
|
||||||
<mat-error *ngIf="form.controls[formfield.controlName].hasError('required')">
|
</mat-form-field>
|
||||||
{{ formfield.label }} is <strong>required</strong>
|
|
||||||
</mat-error>
|
|
||||||
|
|
||||||
</mat-form-field>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<mat-checkbox *ngIf="formfield.controlType==='checkbox'" labelPosition="before" [checked]="formfield.value"
|
|
||||||
[formControlName]="formfield.controlName" [required]="formfield.required">
|
|
||||||
{{ formfield.label }}
|
|
||||||
</mat-checkbox>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
<mat-form-field fxFlexFill *ngIf="formfield.controlType==='datepicker'">
|
||||||
|
<mat-label>{{ formfield.label }}</mat-label>
|
||||||
|
<input matInput [matDatepicker]="datePicker" [min]="formfield.minDate" [max]="formfield.maxDate"
|
||||||
|
[formControlName]="formfield.controlName" [required]="formfield.required">
|
||||||
|
<mat-datepicker-toggle matSuffix [for]="datePicker"></mat-datepicker-toggle>
|
||||||
|
<mat-datepicker #datePicker></mat-datepicker>
|
||||||
|
<mat-error *ngIf="form.controls[formfield.controlName].hasError('required')">
|
||||||
|
{{ formfield.label }} is <strong>required</strong>
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-checkbox *ngIf="formfield.controlType==='checkbox'" labelPosition="before" [checked]="formfield.value"
|
||||||
|
[formControlName]="formfield.controlName" [required]="formfield.required">
|
||||||
|
{{ formfield.label }}
|
||||||
|
</mat-checkbox>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import { FormfieldBase } from './formfield-base';
|
||||||
|
|
||||||
|
export class DatepickerBase extends FormfieldBase {
|
||||||
|
|
||||||
|
controlType = 'datepicker';
|
||||||
|
minDate: Date;
|
||||||
|
maxDate: Date;
|
||||||
|
|
||||||
|
constructor(options: {} = {}) {
|
||||||
|
super(options);
|
||||||
|
this.minDate = options['minDate'] || new Date(2000, 0, 1);
|
||||||
|
this.maxDate = options['maxDate'] || new Date();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -5,7 +5,7 @@ export class InputBase extends FormfieldBase {
|
|||||||
controlType = 'input';
|
controlType = 'input';
|
||||||
type: string;
|
type: string;
|
||||||
|
|
||||||
constructor(options: any) {
|
constructor(options: {} = {}) {
|
||||||
super(options);
|
super(options);
|
||||||
this.type = options['type'] || 'text';
|
this.type = options['type'] || 'text';
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user