New version of communication with service from assets
This commit is contained in:
parent
d985d87086
commit
bf41271041
|
|
@ -24,13 +24,13 @@
|
||||||
|
|
||||||
<div class="form-group row align-items-center">
|
<div class="form-group row align-items-center">
|
||||||
<div class="col-5 col-lg-6 text-start ">
|
<div class="col-5 col-lg-6 text-start ">
|
||||||
<label class="form-label" for="depreciationRate" >Stawka amortyzacyjna:</label>
|
<label class="form-label" for="rate" >Stawka amortyzacyjna:</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-3 col-lg-3">
|
<div class="col-3 col-lg-3">
|
||||||
<input class="form-control" formControlName="depreciationRate" type="number" id="depreciationRate" />
|
<input class="form-control" formControlName="rate" type="number" id="rate" />
|
||||||
</div>
|
</div>
|
||||||
<div class="col-1 col-lg-1 text-start">
|
<div class="col-1 col-lg-1 text-start">
|
||||||
<label for="depreciationRate">%</label>
|
<label for="rate">%</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -60,10 +60,10 @@
|
||||||
@if( TypeDepreciation.digressive === assetsDepreciationFormGroup.get( 'typeDepreciation' )?.value ) {
|
@if( TypeDepreciation.digressive === assetsDepreciationFormGroup.get( 'typeDepreciation' )?.value ) {
|
||||||
<div class="form-group row align-items-center">
|
<div class="form-group row align-items-center">
|
||||||
<div class="col-5 col-lg text-start ">
|
<div class="col-5 col-lg text-start ">
|
||||||
<label for="factorValue" class="form-label">Wspólczynnki degresji</label>
|
<label for="factor" class="form-label">Wspólczynnki degresji</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="col col-lg" >
|
<div class="col col-lg" >
|
||||||
<input type="text" class="form-control" formControlName="factorValue" />
|
<input type="text" class="form-control" formControlName="factor" id="factor" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,16 +3,16 @@ import { ReactiveFormsModule, FormGroup, Validators, FormControl, FormArray } f
|
||||||
import { CurrencyPipe,DecimalPipe,PercentPipe } from '@angular/common';
|
import { CurrencyPipe,DecimalPipe,PercentPipe } from '@angular/common';
|
||||||
|
|
||||||
|
|
||||||
import {Asset, Positions, AssetPlanPosition, TypeDepreciation, YearMonth, AssetLifeChange, YearMonthUtil } from './assets/asset';
|
import {Asset, Positions, AssetPlanPosition, TypeDepreciation, YearMonth, AssetLifeChange, AssetDepreciationMethod, YearMonthUtil } from '../assets/asset';
|
||||||
import {AssetService} from './assets/service/asset.service'
|
import {AssetService} from '../assets/service/asset.service'
|
||||||
|
|
||||||
|
|
||||||
interface FormValues {
|
interface FormValues {
|
||||||
initialValueAsset: number;
|
initialValueAsset: number;
|
||||||
depreciationRate: number;
|
rate: number;
|
||||||
year_month: string;
|
year_month: string;
|
||||||
typeDepreciation: TypeDepreciation;
|
typeDepreciation: TypeDepreciation;
|
||||||
factorValue: number;
|
factor: number;
|
||||||
}
|
}
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-asset-calculator',
|
selector: 'app-asset-calculator',
|
||||||
|
|
@ -22,18 +22,19 @@ templateUrl: "asset-calculator.component.html",
|
||||||
styleUrl: 'asset-calculator.component.css'
|
styleUrl: 'asset-calculator.component.css'
|
||||||
})
|
})
|
||||||
export class AssetCalculatorComponent implements OnInit, OnDestroy{
|
export class AssetCalculatorComponent implements OnInit, OnDestroy{
|
||||||
|
|
||||||
|
TypeDepreciation = TypeDepreciation;
|
||||||
amortizations = new Positions();
|
amortizations = new Positions();
|
||||||
TypeDepreciation = TypeDepreciation;
|
|
||||||
|
|
||||||
lifeFormArray = new FormArray<FormGroup>([]);
|
lifeFormArray = new FormArray<FormGroup>([]);
|
||||||
|
|
||||||
assetsDepreciationFormGroup = new FormGroup( {
|
assetsDepreciationFormGroup = new FormGroup( {
|
||||||
initialValueAsset : new FormControl( 3000, [ Validators.required, this.currencyValidator ]),
|
initialValueAsset : new FormControl( 5000, [ Validators.required, this.currencyValidator ]),
|
||||||
depreciationRate : new FormControl( 20 ) ,
|
rate : new FormControl( 20 ) ,
|
||||||
year_month : new FormControl( "2024-10" ),
|
year_month : new FormControl( "2024-10" ),
|
||||||
typeDepreciation : new FormControl( TypeDepreciation.linear ),
|
typeDepreciation : new FormControl( TypeDepreciation.linear ),
|
||||||
factorValue : new FormControl( 2, [Validators.required,Validators.max(2)] ),
|
factor : new FormControl( 2/*, [Validators.required,Validators.max(2)]*/ ),
|
||||||
|
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
|
@ -43,33 +44,32 @@ export class AssetCalculatorComponent implements OnInit, OnDestroy{
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void{
|
ngOnInit(): void{
|
||||||
const savedAsset = localStorage.getItem('assetForCalculator');
|
const savedAsset = localStorage.getItem('assetForCalculator');
|
||||||
if (savedAsset) this.assetToControls(JSON.parse(savedAsset));
|
if (savedAsset) this.assetToControls(JSON.parse(savedAsset));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {
|
||||||
// Zapisywanie danych przed zniszczeniem komponentu
|
// Zapisywanie danych przed zniszczeniem komponentu
|
||||||
localStorage.setItem('assetForCalculator', JSON.stringify(this.controlsToAsset()));
|
localStorage.setItem('assetForCalculator', JSON.stringify(this.controlsToAsset()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private assetToControls( asset : Asset ) {
|
private assetToControls( asset : Asset ) {
|
||||||
if( asset.life.length > 0 ){
|
if( asset.life.length > 0 ){
|
||||||
const year_month = YearMonthUtil.toString( asset.life[0].when );
|
const year_month = YearMonthUtil.toTxt( asset.life[0].when );
|
||||||
this.assetsDepreciationFormGroup.patchValue({
|
this.assetsDepreciationFormGroup.patchValue({
|
||||||
year_month : year_month,
|
year_month : year_month,
|
||||||
initialValueAsset : asset.life[0].initial,
|
initialValueAsset : asset.life[0].initial,
|
||||||
depreciationRate : asset.depreciationRate,
|
rate : asset.depreciationMethods[0].rate,
|
||||||
typeDepreciation : asset.type,
|
typeDepreciation : asset.depreciationMethods[0].type,
|
||||||
factorValue : asset.factorValue,
|
factor : asset.depreciationMethods[0].factor,
|
||||||
})
|
})
|
||||||
asset.life.slice(1).forEach( lifeChange => {
|
asset.life.slice(1).forEach( lifeChange => {
|
||||||
this.addChangeValue();
|
this.addChangeValue();
|
||||||
const row = this.lifeFormArray.at( this.lifeFormArray.length - 1 ) as FormGroup;
|
const row = this.lifeFormArray.at( this.lifeFormArray.length - 1 ) as FormGroup;
|
||||||
row.patchValue( {
|
row.patchValue( {
|
||||||
initialValueAsset: lifeChange.initial,
|
initialValueAsset: lifeChange.initial,
|
||||||
year_month: YearMonthUtil.toString( lifeChange.when )
|
year_month: YearMonthUtil.toTxt( lifeChange.when )
|
||||||
} );
|
} );
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -79,15 +79,20 @@ export class AssetCalculatorComponent implements OnInit, OnDestroy{
|
||||||
private controlsToAsset() : Asset {
|
private controlsToAsset() : Asset {
|
||||||
|
|
||||||
const formValues = this.assetsDepreciationFormGroup.value as FormValues;
|
const formValues = this.assetsDepreciationFormGroup.value as FormValues;
|
||||||
const when = new YearMonth( formValues.year_month );
|
|
||||||
const asset = new Asset( formValues.depreciationRate, when, formValues.typeDepreciation, formValues.factorValue );
|
const when = new YearMonth( formValues.year_month );
|
||||||
const creationlifeChange = new AssetLifeChange(when, formValues.initialValueAsset , 0, 0);
|
const asset = new Asset( when );
|
||||||
|
|
||||||
|
const method = new AssetDepreciationMethod( when.year, formValues.rate, formValues.typeDepreciation, formValues.factor );
|
||||||
|
asset.addMethod( method );
|
||||||
|
|
||||||
|
const creationlifeChange = new AssetLifeChange( when, formValues.initialValueAsset, 0, 0 );
|
||||||
asset.addChange( creationlifeChange );
|
asset.addChange( creationlifeChange );
|
||||||
|
|
||||||
this.lifeFormArray.controls.forEach(control => {
|
this.lifeFormArray.controls.forEach(control => {
|
||||||
const initialValue = control.get('initialValueAsset')?.value;
|
const initialValue = control.get('initialValueAsset')?.value;
|
||||||
const yearMonth = control.get('year_month')?.value;
|
const yearMonth = control.get('year_month')?.value;
|
||||||
asset.addChange(new AssetLifeChange(new YearMonth(yearMonth), initialValue, 0, 0));
|
asset.addChange( new AssetLifeChange( new YearMonth(yearMonth), initialValue, 0, 0 ) );
|
||||||
})
|
})
|
||||||
|
|
||||||
return asset;
|
return asset;
|
||||||
|
|
|
||||||
|
|
@ -17,14 +17,20 @@ export class YearMonth{
|
||||||
}
|
}
|
||||||
|
|
||||||
export class YearMonthUtil{
|
export class YearMonthUtil{
|
||||||
static toString( ym : YearMonth ):string{
|
|
||||||
|
static toTxt( ym : YearMonth ):string{
|
||||||
return ym.year + '-' + ym.month ;
|
return ym.year + '-' + ym.month ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static toToday( ):YearMonth{
|
||||||
|
const today = new Date();
|
||||||
|
return new YearMonth( today.getFullYear() + '-' +today.getMonth()+1 );
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export class AssetLifeChange{
|
export class AssetLifeChange{
|
||||||
|
|
||||||
readonly when : YearMonth;
|
readonly when : YearMonth;
|
||||||
readonly initial : number;
|
readonly initial : number;
|
||||||
readonly residual : number;
|
readonly residual : number;
|
||||||
|
|
@ -34,37 +40,51 @@ export class AssetLifeChange{
|
||||||
initial : number,
|
initial : number,
|
||||||
residual : number,
|
residual : number,
|
||||||
depreciation: number ){
|
depreciation: number ){
|
||||||
|
|
||||||
this.when = when;
|
this.when = when;
|
||||||
this.initial = initial;
|
this.initial = initial;
|
||||||
this.residual = residual;
|
this.residual = residual;
|
||||||
this.depreciation = depreciation;
|
this.depreciation = depreciation;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class AssetDepreciationMethod{
|
||||||
|
readonly year : number;
|
||||||
|
readonly type : TypeDepreciation;
|
||||||
|
readonly rate : number ;
|
||||||
|
readonly factor : number;
|
||||||
|
|
||||||
|
constructor( year : number,
|
||||||
|
rate : number,
|
||||||
|
type : TypeDepreciation,
|
||||||
|
factor : number ){
|
||||||
|
|
||||||
|
this.year = year;
|
||||||
|
this.rate = rate;
|
||||||
|
this.type = type;
|
||||||
|
this.factor = factor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class Asset {
|
export class Asset {
|
||||||
|
|
||||||
start : YearMonth ;
|
start : YearMonth ;
|
||||||
depreciationRate : number ;
|
|
||||||
type : TypeDepreciation;
|
|
||||||
factorValue : number;
|
|
||||||
life : AssetLifeChange[]=[];
|
|
||||||
|
|
||||||
|
life : AssetLifeChange[]=[];
|
||||||
|
depreciationMethods : AssetDepreciationMethod[]=[];
|
||||||
|
|
||||||
addChange( change : AssetLifeChange ){
|
addChange( change : AssetLifeChange ){
|
||||||
this.life.push( change );
|
this.life.push( change );
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor( depreciationRate : number,
|
addMethod( method : AssetDepreciationMethod ){
|
||||||
start : YearMonth,
|
this.depreciationMethods.push( method );
|
||||||
type : TypeDepreciation,
|
}
|
||||||
factorValue : number ){
|
|
||||||
this.depreciationRate = depreciationRate;
|
constructor( start : YearMonth ){
|
||||||
this.start = start;
|
this.start = start;
|
||||||
this.type = type;
|
|
||||||
this.factorValue = factorValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -73,10 +93,6 @@ export class AssetsContainer{
|
||||||
|
|
||||||
assets: Map<string,Asset> = new Map();
|
assets: Map<string,Asset> = new Map();
|
||||||
|
|
||||||
constructor(){
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
delete( nrInv: string ){
|
delete( nrInv: string ){
|
||||||
this.assets.delete(nrInv);
|
this.assets.delete(nrInv);
|
||||||
}
|
}
|
||||||
|
|
@ -12,7 +12,7 @@ import { Observable } from 'rxjs';
|
||||||
})
|
})
|
||||||
export class AssetService {
|
export class AssetService {
|
||||||
|
|
||||||
// private assetUrl: string ='http://localhost:8800/rest-api/assets/calculate';
|
// private assetUrl: string ='http://localhost:8800/rest-api/assets/calculate';
|
||||||
|
|
||||||
//private assetUrl: string ='http://localhost:5001/rest-api/assets/calculate';
|
//private assetUrl: string ='http://localhost:5001/rest-api/assets/calculate';
|
||||||
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { Component } from '@angular/core';
|
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||||
import { AssetsContainer, Asset, TypeDepreciation, YearMonth } from '../asset-calculator/assets/asset';
|
import { Asset, TypeDepreciation, YearMonthUtil, AssetLifeChange } from '../assets/asset';
|
||||||
import { ReactiveFormsModule, FormBuilder, FormGroup, Validators, FormControl, FormArray} from '@angular/forms';
|
import { ReactiveFormsModule, FormBuilder, FormGroup, FormArray, ValidatorFn, ValidationErrors, AbstractControl } from '@angular/forms';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
|
@ -19,8 +20,8 @@ import { ReactiveFormsModule, FormBuilder, FormGroup, Validators, FormControl, F
|
||||||
<th class="col-2">Numer inwentarzowy</th>
|
<th class="col-2">Numer inwentarzowy</th>
|
||||||
<th class="col-2">Wartość</th>
|
<th class="col-2">Wartość</th>
|
||||||
<th class="col-2">Metoda amortyzacji</th>
|
<th class="col-2">Metoda amortyzacji</th>
|
||||||
<th class="col-2">Stawka</th>
|
<!-- <th class="col-2">Stawka</th>
|
||||||
<th class="col-2"></th>
|
<th class="col-2"></th> -->
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
|
|
@ -28,15 +29,16 @@ import { ReactiveFormsModule, FormBuilder, FormGroup, Validators, FormControl, F
|
||||||
|
|
||||||
@for( assetFormGroup of assetFormArray.controls; track $index ) {
|
@for( assetFormGroup of assetFormArray.controls; track $index ) {
|
||||||
<tr [formGroup] = "assetFormGroup">
|
<tr [formGroup] = "assetFormGroup">
|
||||||
<td> <input class="form-control" formControlName="nr" type="text" readonly></td>
|
<td> <input class="form-control" formControlName="nrInv" type="text" readonly></td>
|
||||||
<td> <input class="form-control" formControlName="initialValue" type="number" placeholder="Wprowadź wartość"></td>
|
<td> <input class="form-control" formControlName="initialValue" type="number" placeholder="Wprowadź wartość"></td>
|
||||||
<td>
|
|
||||||
<select class="form-select" formControlName="typeDepreciation" >
|
<!-- <td>
|
||||||
|
<select class="form-select" formControlName="typeDepreciation" >
|
||||||
<option [ngValue]=TypeDepreciation.linear selected="selected">Liniowa</option>
|
<option [ngValue]=TypeDepreciation.linear selected="selected">Liniowa</option>
|
||||||
<option [ngValue]=TypeDepreciation.digressive >Dygresywna</option>
|
<option [ngValue]=TypeDepreciation.digressive >Dygresywna</option>
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
<td> <input class="form-control" formControlName="depreciationRate" type="number" /> </td>
|
<td> <input class="form-control" formControlName="depreciationRate" type="number" /> </td> -->
|
||||||
|
|
||||||
<td class="col-2">
|
<td class="col-2">
|
||||||
<input type="button" class="btn btn-outline-secondary" (click)="delete($index)" value="Usuń Składnik">
|
<input type="button" class="btn btn-outline-secondary" (click)="delete($index)" value="Usuń Składnik">
|
||||||
|
|
@ -50,55 +52,92 @@ import { ReactiveFormsModule, FormBuilder, FormGroup, Validators, FormControl, F
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input type="button" (click)=addNew() class="btn btn-outline-secondary" value="Dodaj Składnik">
|
<input type="button" (click)=addNew() class="btn btn-outline-secondary" value="Dodaj Składnik">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
`,
|
`,
|
||||||
styleUrl: './fixed-asset.component.css'
|
styleUrl: './fixed-asset.component.css'
|
||||||
})
|
})
|
||||||
export class FixedAssetComponent {
|
export class FixedAssetComponent {
|
||||||
|
|
||||||
|
static STORAGE_KEY = "fixed_assets";
|
||||||
|
|
||||||
static indexNr = 1;
|
static indexNr = 1;
|
||||||
|
|
||||||
TypeDepreciation = TypeDepreciation;
|
TypeDepreciation = TypeDepreciation;
|
||||||
|
|
||||||
assetsContainer : AssetsContainer;
|
|
||||||
|
|
||||||
|
|
||||||
assetFormArray : FormArray<FormGroup>;
|
assetFormArray : FormArray<FormGroup>;
|
||||||
|
|
||||||
|
|
||||||
constructor( private fb: FormBuilder ){
|
constructor( private fb: FormBuilder ){
|
||||||
|
|
||||||
this.assetsContainer = new AssetsContainer ();
|
|
||||||
this.assetFormArray = this.fb.array<FormGroup>([])
|
this.assetFormArray = this.fb.array<FormGroup>([])
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
const savedAssets = localStorage.getItem( FixedAssetComponent.STORAGE_KEY) ;
|
||||||
|
if( savedAssets ) {
|
||||||
|
this.assetsToControls( JSON.parse( savedAssets ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
localStorage.setItem( FixedAssetComponent.STORAGE_KEY, JSON.stringify( this.controlsToAssets() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private assetsToControls( assetsArray: [ string, Asset ][]) {
|
||||||
|
const assetsMap = new Map<string, Asset>( assetsArray );
|
||||||
|
assetsMap.forEach( (asset, key) => {
|
||||||
|
this.addRow( key, asset.life[0].initial );
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private controlsToAssets(): [string, Asset][] {
|
||||||
|
|
||||||
|
const assets = new Map<string, Asset>();
|
||||||
|
this.assetFormArray.controls.forEach( control => {
|
||||||
|
|
||||||
|
const nrInv = control.get('nrInv')?.value;
|
||||||
|
const initialValue = control.get('initialValue')?.value;
|
||||||
|
const yearMonth = YearMonthUtil.toToday();
|
||||||
|
const asset = new Asset( yearMonth );
|
||||||
|
const assetLifeChange = new AssetLifeChange( yearMonth, initialValue, 0, 0 );
|
||||||
|
asset.addChange( assetLifeChange );
|
||||||
|
assets.set( nrInv, asset );
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
return Array.from( assets.entries() );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delete( index : number ){
|
delete( index : number ){
|
||||||
this.assetFormArray.removeAt( index );
|
this.assetFormArray.removeAt( index );
|
||||||
}
|
}
|
||||||
|
|
||||||
addNew(){
|
addNew(){
|
||||||
this.addNr("NrInv" + FixedAssetComponent.indexNr++ );
|
this.addRow( "NrInv" + FixedAssetComponent.indexNr++, 1000 );
|
||||||
}
|
}
|
||||||
|
|
||||||
addNr( nrInv:string ):void{
|
addRow( nrInv_:string, initial_: number ):void{
|
||||||
|
|
||||||
|
const newRow = this.fb.group({
|
||||||
|
nrInv : [ nrInv_ ],
|
||||||
|
initialValue : [ initial_ ],
|
||||||
|
});
|
||||||
|
|
||||||
const today = new Date();
|
// typeDepreciation : [ TypeDepreciation.linear ],
|
||||||
const year = today.getFullYear();
|
// depreciationRate : [ 10 ],
|
||||||
const month = today.getMonth() + 1;
|
// year_month : [ year_month ]
|
||||||
const year_month = year +'-'+month;
|
|
||||||
const yearMonth = new YearMonth( year_month ) ;
|
|
||||||
const asset = new Asset( 20, yearMonth, TypeDepreciation.linear, 10 );
|
|
||||||
|
|
||||||
const newRow= this.fb.group({
|
|
||||||
nr : [ nrInv ],
|
|
||||||
initialValue : [ 10000 ],
|
|
||||||
depreciationRate : [ 10 ],
|
|
||||||
typeDepreciation : [ TypeDepreciation.linear ],
|
|
||||||
year_month : [ year_month ]
|
|
||||||
})
|
|
||||||
this.assetFormArray.push( newRow );
|
this.assetFormArray.push( newRow );
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// uniqueColumnValidator(): ValidatorFn {
|
||||||
|
// return (control: AbstractControl): ValidationErrors | null => {
|
||||||
|
|
||||||
|
// const values = this.assetFormArray.map(field => field.value) || [];
|
||||||
|
// const uniqueValues = new Set(values);
|
||||||
|
// return uniqueValues.size !== values.length ? { uniqueColumn: true } : null;
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';
|
||||||
|
|
||||||
|
export function uniqueColumnValidator(columnName: string): ValidatorFn {
|
||||||
|
return (control: AbstractControl): ValidationErrors | null => {
|
||||||
|
const formArray = control.get(columnName) as AbstractControl[];
|
||||||
|
const values = formArray?.map(field => field.value) || [];
|
||||||
|
const uniqueValues = new Set(values);
|
||||||
|
return uniqueValues.size !== values.length ? { uniqueColumn: true } : null;
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue