New version of asset calculator on signals
This commit is contained in:
parent
8893499650
commit
8f86c6ed53
|
|
@ -10,7 +10,7 @@ import { FriendlyPagesComponent } from './friendly-pages/friendly-pages.componen
|
|||
export const routes: Routes = [
|
||||
{
|
||||
path: "",
|
||||
title: "Sygnały",
|
||||
title: "Kalkulator amortyzacyjny",
|
||||
component:AssetCalculatorComponent
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,37 +4,39 @@
|
|||
|
||||
|
||||
<div class="row">
|
||||
<div class="h1 text-center text-lg-start" i18n="@@depreciationCalculator">
|
||||
<div class="h1 text-center text-lg-start">
|
||||
{{ 'asset-calculator.depreciationCalculator' | translate }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col mx-2 mx-lg-0 mb-2 col-lg-4 frame">
|
||||
<div class="row text-center h5 "><h5 i18n="@@fixedAsset">{{ 'asset-calculator.fixedAsset' | translate }}</h5></div>
|
||||
<form [formGroup]=assetsDepreciationFormGroup >
|
||||
<div class="row text-center h5 "><h5>{{ 'asset-calculator.fixedAsset' | translate }}</h5></div>
|
||||
<div class="form-group row align-items-center mb-1">
|
||||
<div class="col-5 col-lg-6 text-start">
|
||||
<label class="form-label" for="initialValueAsset" i18n="@@initialValue" >
|
||||
<label class="form-label" for="initialValueAsset" >
|
||||
{{ 'asset-calculator.initialValue' | translate }}</label>
|
||||
</div>
|
||||
<div class="col col-lg">
|
||||
<input class="form-control" formControlName="initialValueAsset" type="number" id="initialValueAsset" required >
|
||||
<input class="form-control" [(ngModel)]="initialValueAsset"
|
||||
type="number"
|
||||
id="initialValueAsset"
|
||||
required >
|
||||
|
||||
@if(assetsDepreciationFormGroup.get('initialValueSet')?.invalid && assetsDepreciationFormGroup.get('initialValueSet')?.touched){
|
||||
<!-- @if(assetsDepreciationFormGroup.get('initialValueSet')?.invalid && assetsDepreciationFormGroup.get('initialValueSet')?.touched){
|
||||
<div class="text-danger col-auto"> Wartość niepoprawna!. Podaj kwotę w zł np 3000.05 (czyli 3000 zł i 5 gr)</div>
|
||||
}@else{
|
||||
}
|
||||
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row align-items-center">
|
||||
<div class="col-5 col-lg-6 text-start ">
|
||||
<label class="form-label" for="rate" >{{ 'asset-calculator.depreciationRate' | translate }}</label>
|
||||
<label class="form-label" for="rate" >{{ 'asset-calculator.depreciationRate' | translate }}</label>
|
||||
</div>
|
||||
<div class="col-3 col-lg-3">
|
||||
<input class="form-control" formControlName="rate" type="number" id="rate" />
|
||||
<input class="form-control" [(ngModel)]="rate" type="number" id="rate" />
|
||||
</div>
|
||||
<div class="col-1 col-lg-1 text-start">
|
||||
<label for="rate">%</label>
|
||||
|
|
@ -46,7 +48,7 @@
|
|||
<label class="form-label" for="startDepreciation" >{{ 'asset-calculator.startOfDepreciation' | translate }} </label>
|
||||
</div>
|
||||
<div class="col-7 col-lg-6">
|
||||
<input type="month" lang="pl" class="form-control" formControlName="startDepreciation" id="startDepreciation" placeholder="2024" />
|
||||
<input type="month" lang="pl" class="form-control" [(ngModel)]="startDepreciation" id="startDepreciation" placeholder="2024" />
|
||||
|
||||
</div>
|
||||
|
||||
|
|
@ -57,54 +59,53 @@
|
|||
<label class="form-label" for="typeDepreciation" >{{ 'asset-calculator.depreciationMethod' | translate }}</label>
|
||||
</div>
|
||||
<div class="col col-lg" >
|
||||
<select class="form-select" formControlName="typeDepreciation" id="typeDepreciation" >
|
||||
<select class="form-select" [(ngModel)]="typeDepreciation" id="typeDepreciation" >
|
||||
<option [ngValue]=TypeDepreciation.linear selected="selected" >{{ 'asset-calculator.linear' | translate }}</option>
|
||||
<option [ngValue]=TypeDepreciation.digressive >{{ 'asset-calculator.digressive' | translate }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if( TypeDepreciation.digressive === assetsDepreciationFormGroup.get( 'typeDepreciation' )?.value ) {
|
||||
|
||||
@if( TypeDepreciation.digressive === typeDepreciation() ) {
|
||||
<div class="form-group row align-items-center">
|
||||
<div class="col-5 col-lg text-start ">
|
||||
<label for="factor" class="form-label">{{ 'asset-calculator.degressionCoefficients' | translate }}</label>
|
||||
</div>
|
||||
<div class="col col-lg" >
|
||||
<input type="text" class="form-control" (click)=addChangeValue() formControlName="factor" id="factor" />
|
||||
<input type="text" class="form-control" [(ngModel)]="factor" id="factor" />
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</form>
|
||||
}
|
||||
<div class="col-1">
|
||||
<input class="btn btn-secondary col-auto" name="addChangeValue"
|
||||
[disabled]=assetsDepreciationFormGroup.invalid (click)=addChangeValue() type="button" value="{{ 'asset-calculator.addChangeValue' | translate }}">
|
||||
(click)=addLifeChange() type="button" value="{{ 'asset-calculator.addChangeValue' | translate }}">
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
@if( lifeFormArray.controls.length > 0 ){
|
||||
@if( lifeChangesSignal().length > 0 ){
|
||||
<div class="col col-lg-6 mb-2 ms-lg-3">
|
||||
<div class="row">
|
||||
<div class="h5 text-center my-1" ><h5 i18n="@@valueChanges">{{ 'asset-calculator.valueChanges' | translate }}</h5></div>
|
||||
<div class="h5 text-center my-1" ><h5>{{ 'asset-calculator.valueChanges' | translate }}</h5></div>
|
||||
</div>
|
||||
<div class="row p-2 ">
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-1 text-center" scope="col-auto">{{ 'asset-calculator.lp' | translate }}</th>
|
||||
<th class="col-2 text-center" scope="col-auto" i18n="@@month">{{ 'asset-calculator.month' | translate }}</th>
|
||||
<th class="col-2 text-center" scope="col" i18n="@@change">{{ 'asset-calculator.change' | translate }}</th>
|
||||
<th class="col-1 text-center" scope="col-auto"> {{ 'asset-calculator.lp' | translate }}</th>
|
||||
<th class="col-2 text-center" scope="col-auto"> {{ 'asset-calculator.month' | translate }}</th>
|
||||
<th class="col-2 text-center" scope="col" > {{ 'asset-calculator.change' | translate }}</th>
|
||||
<th class="col-1 text-center" scope="col"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@for( changeGroup of lifeFormArray.controls; track $index ) {
|
||||
<tr [formGroup] = changeGroup >
|
||||
@for( life of lifeChangesSignal(); track $index ) {
|
||||
<tr >
|
||||
<th class="align-middle text-center col-auto" scope="row">{{$index+1}}</th>
|
||||
<td><input class="form-control" type="month" formControlName="year_month" ></td>
|
||||
<td><input class="form-control" type="number" formControlName="initialValueAsset" placeholder="Wprowadź wartość {{$index}}"></td>
|
||||
<td ><button class="btn btn-sm btn-secondary" type="button" (click)=removeChange($index)>{{ 'asset-calculator.remove' | translate }}</button>
|
||||
<td><input class="form-control" type="month" [(ngModel)]="life.when" ></td>
|
||||
<td><input class="form-control" type="number" [(ngModel)]="life.initial" placeholder="Wprowadź wartość {{$index}}"></td>
|
||||
<td><button class="btn btn-sm btn-secondary" type="button" (click)=removeLifeChange($index)>{{ 'asset-calculator.remove' | translate }}</button>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
|
|
@ -130,7 +131,7 @@
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@for (position of amortizations; track $index) {
|
||||
@for (position of amortizationsSignal(); track $index) {
|
||||
<tr [class]="clazz(position)" class="text-center">
|
||||
<th scope="row" >{{$index+1}}</th>
|
||||
<td>{{ position.when.year }}</td>
|
||||
|
|
@ -138,7 +139,7 @@
|
|||
<td>{{ position.calculatedDepreciation | number:'1.2-2' }}</td>
|
||||
<td>{{ position.sum | number:'1.2-2' }}</td>
|
||||
</tr>
|
||||
@if( 12 === position.when.month || $index === amortizations.length-1){
|
||||
@if( 12 === position.when.month || $index === amortizationsSignal.length-1){
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
</td>
|
||||
|
|
|
|||
|
|
@ -1,178 +1,219 @@
|
|||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { ReactiveFormsModule, FormGroup, Validators, FormControl, FormBuilder, AbstractControl } from '@angular/forms';
|
||||
import { DecimalPipe } from '@angular/common';
|
||||
|
||||
import {Asset, AssetPlanPosition, TypeDepreciation, YearMonth, AssetLifeChange, AssetDepreciationMethod, YearMonthUtil } from '../assets/asset';
|
||||
import {AssetService} from '../assets/service/asset.service'
|
||||
import {TranslateModule} from "@ngx-translate/core";
|
||||
|
||||
import { Component, signal, effect, computed } from '@angular/core';
|
||||
import { DecimalPipe} from '@angular/common';
|
||||
import { Asset, AssetPlanPosition, TypeDepreciation, YearMonth, AssetLifeChange, AssetDepreciationMethod } from '../assets/asset';
|
||||
import { AssetService } from '../assets/service/asset.service';
|
||||
import { TranslateModule, TranslateService } from "@ngx-translate/core";
|
||||
import { FormsModule } from '@angular/forms';
|
||||
|
||||
interface FormValues {
|
||||
initialValueAsset: number;
|
||||
initialValueAsset:number;
|
||||
rate: number;
|
||||
startDepreciation: string;
|
||||
typeDepreciation: TypeDepreciation;
|
||||
factor: number;
|
||||
}
|
||||
@Component({
|
||||
selector: 'app-asset-calculator',
|
||||
standalone: true,
|
||||
imports: [ DecimalPipe, ReactiveFormsModule, TranslateModule ] ,
|
||||
templateUrl: "asset-calculator.component.html",
|
||||
styleUrl: 'asset-calculator.component.css'
|
||||
})
|
||||
export class AssetCalculatorComponent implements OnInit, OnDestroy{
|
||||
|
||||
TypeDepreciation = TypeDepreciation;
|
||||
class AssetLifeChangeWrapper{
|
||||
|
||||
lifeFormArray ;
|
||||
assetsDepreciationFormGroup : FormGroup;
|
||||
amortizations : AssetPlanPosition[]=[];
|
||||
when = signal<string> ( YearMonth.todayTxt());
|
||||
initial = signal<number>( 0 );
|
||||
|
||||
constructor(private fb: FormBuilder,
|
||||
private assetService : AssetService){
|
||||
get(): AssetLifeChange {
|
||||
const ym = this.when();
|
||||
const when = YearMonth.from( ym );
|
||||
return new AssetLifeChange( when, this.initial() , 0, 0 );
|
||||
}
|
||||
|
||||
this.assetsDepreciationFormGroup = new FormGroup({
|
||||
initialValueAsset : new FormControl<number>( 6000, [ Validators.required, this.currencyValidator ]),
|
||||
rate : new FormControl<number>( 20 ) ,
|
||||
startDepreciation : new FormControl<string>( new Date().toISOString().slice(0, 7) ),
|
||||
typeDepreciation : new FormControl<TypeDepreciation>( TypeDepreciation.linear ),
|
||||
factor : new FormControl<number>( 2/*, [Validators.required,Validators.max(2)]*/ ),
|
||||
|
||||
} as {
|
||||
[key in keyof FormValues]: FormControl<FormValues[key]>
|
||||
});
|
||||
this.lifeFormArray = this.fb.array<FormGroup>([]);
|
||||
constructor( assetLifeChange : AssetLifeChange ){
|
||||
|
||||
this.assetsDepreciationFormGroup.valueChanges.subscribe( () => this.calculate() );
|
||||
this.lifeFormArray.valueChanges.subscribe( () => this.calculate() );
|
||||
this.when.set( YearMonth.toTxt( assetLifeChange.when ) );
|
||||
this.initial.set( assetLifeChange.initial );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
ngOnInit(): void{
|
||||
const savedAsset = localStorage.getItem('assetForCalculator');
|
||||
if (savedAsset) this.assetToControls(JSON.parse(savedAsset));
|
||||
this.calculate();
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
const asset = this.controlsToAsset();
|
||||
// Zapisywanie danych przed zniszczeniem komponentu
|
||||
this.saveInStorage( asset );
|
||||
}
|
||||
|
||||
private saveInStorage( asset : Asset ) {
|
||||
localStorage.setItem('assetForCalculator', JSON.stringify(asset));
|
||||
}
|
||||
|
||||
private assetToControls( asset : Asset ) {
|
||||
if( asset.life.length > 0 ){
|
||||
const year_month = YearMonthUtil.toTxt( asset.life[0].when );
|
||||
this.assetsDepreciationFormGroup.patchValue({
|
||||
year_month : year_month,
|
||||
initialValueAsset : asset.life[0].initial,
|
||||
rate : asset.depreciationMethods[0].rate,
|
||||
typeDepreciation : asset.depreciationMethods[0].type,
|
||||
factor : asset.depreciationMethods[0].factor,
|
||||
})
|
||||
asset.life.slice(1).forEach( lifeChange => {
|
||||
this.addChangeValue();
|
||||
const row = this.lifeFormArray.at( this.lifeFormArray.length - 1 ) as FormGroup;
|
||||
row.patchValue( {
|
||||
initialValueAsset: lifeChange.initial,
|
||||
year_month: YearMonthUtil.toTxt( lifeChange.when )
|
||||
} );
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private controlsToAsset() : Asset {
|
||||
|
||||
const formValues = this.assetsDepreciationFormGroup.getRawValue() as FormValues;
|
||||
|
||||
const when = new YearMonth( formValues.startDepreciation);
|
||||
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 );
|
||||
|
||||
this.lifeFormArray.controls.forEach(control => {
|
||||
const initialValue = control.get('initialValueAsset')?.value;
|
||||
const yearMonth = control.get('year_month')?.value;
|
||||
asset.addChange( new AssetLifeChange( new YearMonth(yearMonth), initialValue, 0, 0 ) );
|
||||
})
|
||||
|
||||
return asset;
|
||||
}
|
||||
|
||||
calculate(){
|
||||
const asset = this.controlsToAsset();
|
||||
this.saveInStorage( asset );
|
||||
this.assetService.calculate(asset).subscribe(positions => {
|
||||
this.calculateToValues(positions);
|
||||
this.amortizations = positions;
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
calculateForAsset( asset : Asset ) {
|
||||
this.assetService.calculate( asset ).subscribe(
|
||||
positions => {
|
||||
this.calculateToValues( positions );
|
||||
this.amortizations = positions });
|
||||
|
||||
}
|
||||
|
||||
calculateToValues( positions:AssetPlanPosition[] ) {
|
||||
let sum = 0;
|
||||
let sumThisYear = 0;
|
||||
positions.forEach(position => {
|
||||
position.calculatedDepreciation *= 0.01;
|
||||
sum += position.calculatedDepreciation;
|
||||
position.sum = sum;
|
||||
|
||||
if (position.when.month === 1) {
|
||||
sumThisYear = position.calculatedDepreciation;
|
||||
} else {
|
||||
sumThisYear += position.calculatedDepreciation;
|
||||
}
|
||||
position.sumThisYear = sumThisYear;
|
||||
});
|
||||
}
|
||||
|
||||
clazz(pos : AssetPlanPosition ){
|
||||
|
||||
return pos.when.year % 2 === 0 ? "table-light" : "table-dark";
|
||||
}
|
||||
|
||||
// Walidator dla kwoty
|
||||
currencyValidator(control: AbstractControl) {
|
||||
const value = control.value;
|
||||
const regex = /^\d+(\.\d{1,2})?$/; // Akceptuje liczby z maksymalnie dwoma miejscami po przecinku
|
||||
return regex.test(value) ? null : { invalidCurrency: true };
|
||||
}
|
||||
|
||||
addChangeValue() {
|
||||
const formValues = this.assetsDepreciationFormGroup.value as FormValues;
|
||||
|
||||
const change = new AssetLifeChange(new YearMonth( formValues.startDepreciation ), 1000, 0, 0 );
|
||||
|
||||
const newFormGroup = new FormGroup( { initialValueAsset: new FormControl( change.initial ),
|
||||
year_month : new FormControl( formValues.startDepreciation )})
|
||||
|
||||
this.lifeFormArray.push(newFormGroup);
|
||||
|
||||
}
|
||||
|
||||
removeChange(index: number) {
|
||||
|
||||
this.lifeFormArray.removeAt(index);
|
||||
}
|
||||
}
|
||||
const NAME_IN_STORAGE = 'assetForCalculator';
|
||||
@Component({
|
||||
selector: 'app-asset-calculator',
|
||||
standalone: true,
|
||||
imports: [DecimalPipe, TranslateModule, FormsModule],
|
||||
templateUrl: "asset-calculator.component.html",
|
||||
styleUrls: ['asset-calculator.component.css']
|
||||
})
|
||||
export class AssetCalculatorComponent {
|
||||
|
||||
TypeDepreciation = TypeDepreciation;
|
||||
|
||||
// Signals for form state and amortizations
|
||||
|
||||
initialValueAsset = signal <number> ( 6000 );
|
||||
rate = signal <number> ( 20 );
|
||||
startDepreciation = signal <string> ( YearMonth.today().toString() );
|
||||
typeDepreciation = signal <TypeDepreciation>( TypeDepreciation.linear );
|
||||
factor = signal <number>( 2 );
|
||||
|
||||
formValues = computed<FormValues>(() => {
|
||||
return {
|
||||
initialValueAsset: this.initialValueAsset(),
|
||||
rate: this.rate(),
|
||||
startDepreciation: this.startDepreciation(),
|
||||
typeDepreciation: this.typeDepreciation(),
|
||||
factor: this.factor(),
|
||||
};
|
||||
});
|
||||
|
||||
lifeChangesSignal = signal<AssetLifeChangeWrapper[]>([]); // Replaces `lifeFormArray`
|
||||
|
||||
amortizationsSignal =signal<AssetPlanPosition[]>([]);
|
||||
|
||||
constructor( private assetService: AssetService,
|
||||
private translate : TranslateService ) {
|
||||
// Effect to recalculate when form values change
|
||||
effect( () => this.reCalculate( ) )
|
||||
|
||||
}
|
||||
|
||||
ngOnInit(): void{
|
||||
this.restoreState();
|
||||
}
|
||||
|
||||
|
||||
ngOnDestroy(): void {
|
||||
const asset = this.controlsToAsset( );
|
||||
if( null != asset){
|
||||
this.saveState( asset );
|
||||
}
|
||||
}
|
||||
|
||||
private restoreState() {
|
||||
const savedAsset = localStorage.getItem(NAME_IN_STORAGE);
|
||||
if( savedAsset ) {
|
||||
try {
|
||||
const parsedAsset : Asset = JSON.parse(savedAsset);
|
||||
this.assetToControls( parsedAsset );
|
||||
} catch (error) {
|
||||
console.error('Failed to parse saved asset:', error);
|
||||
localStorage.removeItem(NAME_IN_STORAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private saveState(asset:Asset) {
|
||||
|
||||
// Zapisywanie danych przed zniszczeniem komponentu
|
||||
try {
|
||||
// Serialize the asset to a JSON string
|
||||
localStorage.setItem(NAME_IN_STORAGE, JSON.stringify(asset) );
|
||||
|
||||
} catch (error) {
|
||||
console.error('Failed to save asset:', error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private assetToControls( asset : Asset ) {
|
||||
if( asset.life.length > 0 ){
|
||||
this.updateBatch(asset);
|
||||
}
|
||||
}
|
||||
|
||||
private updateBatch(asset: Asset) {
|
||||
const life0 = asset.life[0];
|
||||
const method0 = asset.depreciationMethods[0];
|
||||
this.initialValueAsset.set(life0.initial);
|
||||
const ymText =YearMonth.toTxt( life0.when );
|
||||
this.startDepreciation.set(ymText);
|
||||
this.rate.set(method0.rate);
|
||||
this.typeDepreciation.set(method0.type);
|
||||
this.factor.set(method0.rate);
|
||||
|
||||
console.log( asset.life );
|
||||
for( let i = 1; i < asset.life.length ; i++ ){
|
||||
const assetLifeChange = asset.life[i];
|
||||
const lifeChangeWrapper = this.addLifeChange2(assetLifeChange);
|
||||
lifeChangeWrapper.initial.set( assetLifeChange.initial );
|
||||
lifeChangeWrapper.when.set(YearMonth.toTxt( assetLifeChange.when ));
|
||||
};
|
||||
}
|
||||
|
||||
private controlsToAsset(): Asset {
|
||||
|
||||
const formValues = this.formValues();
|
||||
const lifeChanges = this.lifeChangesSignal();
|
||||
|
||||
const when = YearMonth.from( formValues.startDepreciation );
|
||||
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 );
|
||||
|
||||
lifeChanges.forEach((lifeChange) => {
|
||||
asset.addChange( lifeChange.get() );
|
||||
});
|
||||
|
||||
return asset;
|
||||
}
|
||||
|
||||
private calculateToValues( positions:AssetPlanPosition[] ) {
|
||||
let sum = 0;
|
||||
let sumThisYear = 0;
|
||||
positions.forEach( position => {
|
||||
// From gr to zł or from cents to dollars it depends from currency
|
||||
position.calculatedDepreciation *= 0.01;
|
||||
sum += position.calculatedDepreciation;
|
||||
position.sum = sum;
|
||||
|
||||
if( position.when.month === 1 ) {
|
||||
sumThisYear = position.calculatedDepreciation;
|
||||
} else {
|
||||
sumThisYear += position.calculatedDepreciation;
|
||||
}
|
||||
position.sumThisYear = sumThisYear;
|
||||
});
|
||||
}
|
||||
|
||||
private reCalculate() {
|
||||
|
||||
const asset = this.controlsToAsset( );
|
||||
this.calculateAmortizationsForAsset(asset);
|
||||
this.saveState(asset);
|
||||
|
||||
}
|
||||
|
||||
private calculateAmortizationsForAsset(asset: Asset) {
|
||||
this.assetService.calculate(asset).subscribe((positions) => {
|
||||
this.calculateToValues(positions);
|
||||
this.amortizationsSignal.set(positions);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
clazz(pos : AssetPlanPosition ){
|
||||
return pos.when.year % 2 === 0 ? "table-light" : "table-dark";
|
||||
}
|
||||
|
||||
// Method to add a life change
|
||||
addLifeChange( ) {
|
||||
const assetLifeChange2 : AssetLifeChange
|
||||
= new AssetLifeChange( YearMonth.from( this.formValues().startDepreciation ), 1000, 0, 0 );
|
||||
return this.addLifeChange2( assetLifeChange2 );
|
||||
|
||||
}
|
||||
|
||||
addLifeChange2( assetLifeChange : AssetLifeChange ) {
|
||||
const newChangeWrapper = new AssetLifeChangeWrapper( assetLifeChange );
|
||||
this.lifeChangesSignal.update((changes) => [...changes, newChangeWrapper]);
|
||||
return newChangeWrapper;
|
||||
}
|
||||
|
||||
// Method to remove a life change
|
||||
removeLifeChange(index: number) {
|
||||
this.lifeChangesSignal.update((changes) =>
|
||||
changes.filter((_, i) => i !== index)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -5,29 +5,44 @@ export enum TypeDepreciation{
|
|||
|
||||
export class YearMonth{
|
||||
|
||||
static from( year_month : string) {
|
||||
const [year, month] = year_month.split('-').map(Number);
|
||||
return new YearMonth( year, month );
|
||||
}
|
||||
|
||||
readonly year : number ;
|
||||
readonly month : number ;
|
||||
constructor( year_month:string ){
|
||||
const [year, month] = year_month.split('-').map(Number);
|
||||
|
||||
constructor( year:number, month : number ){
|
||||
this.year = year;
|
||||
this.month = month;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class YearMonthUtil{
|
||||
|
||||
static toTxt( ym : YearMonth ):string{
|
||||
return ym.year + '-' + ym.month ;
|
||||
}
|
||||
|
||||
static today( ):YearMonth{
|
||||
const today = new Date();
|
||||
return new YearMonth( today.getFullYear() + '-' +today.getMonth()+1 );
|
||||
return new YearMonth( today.getFullYear() , today.getMonth()+1 );
|
||||
}
|
||||
|
||||
}
|
||||
static todayTxt( ):string{
|
||||
const today = new Date();
|
||||
return YearMonth.toTxt ( YearMonth.today());
|
||||
}
|
||||
static toTxt( ym : YearMonth ):string{
|
||||
return ym.year + '-' + String(ym.month).padStart(2, '0');;
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return { year: this.year, month: this.month };
|
||||
}
|
||||
|
||||
static fromJSON(json: { year: number; month: number }): YearMonth {
|
||||
return new YearMonth(json.year, json.month);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
export class AssetLifeChange{
|
||||
|
||||
|
|
@ -113,7 +128,7 @@ export class AssetsContainer{
|
|||
}
|
||||
|
||||
export class AssetPlanPosition{
|
||||
when : YearMonth = new YearMonth('0-0');
|
||||
when : YearMonth = new YearMonth(0,0);
|
||||
calculatedDepreciation = 0;
|
||||
sum = 0;
|
||||
sumThisYear = 0;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { Asset, TypeDepreciation, YearMonthUtil, AssetLifeChange } from '../assets/asset';
|
||||
import { Asset, TypeDepreciation, YearMonth, AssetLifeChange } from '../assets/asset';
|
||||
import { ReactiveFormsModule, FormBuilder, FormGroup, FormArray, ValidatorFn, ValidationErrors, AbstractControl } from '@angular/forms';
|
||||
|
||||
|
||||
|
|
@ -96,7 +96,7 @@ export class FixedAssetComponent {
|
|||
|
||||
const nrInv = control.get('nrInv')?.value;
|
||||
const initialValue = control.get('initialValue')?.value;
|
||||
const yearMonth = YearMonthUtil.today();
|
||||
const yearMonth = YearMonth.today();
|
||||
const asset = new Asset( yearMonth );
|
||||
const assetLifeChange = new AssetLifeChange( yearMonth, initialValue, 0, 0 );
|
||||
asset.addChange( assetLifeChange );
|
||||
|
|
|
|||
Loading…
Reference in New Issue