New version of communication with service from assets

This commit is contained in:
Artur 2024-11-04 22:49:41 +01:00
parent d985d87086
commit bf41271041
9 changed files with 148 additions and 79 deletions

View File

@ -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>
} }

View File

@ -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;

View File

@ -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);
} }

View File

@ -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';

View File

@ -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;
// };
// }
} }

View File

@ -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;
};