diff --git a/src/main/frontend/src/app/component/expense/settlement-dialog/settlement-dialog.component.html b/src/main/frontend/src/app/component/expense/settlement-dialog/settlement-dialog.component.html index b1066e5..b3851b2 100644 --- a/src/main/frontend/src/app/component/expense/settlement-dialog/settlement-dialog.component.html +++ b/src/main/frontend/src/app/component/expense/settlement-dialog/settlement-dialog.component.html @@ -3,10 +3,11 @@

Rozliczenie dla grupy {{ data.group.groupName }}

@if (data.debts) {
@for (settlement of data.debts | keyvalue; track settlement) { -

{{ settlement.key }}

- @if (settlement.key !== 'PLN') { - przelicz do PLN - } +

{{ settlement.key }} + @if (settlement.key !== 'PLN') { + przelicz do PLN + } +

@for (debt of settlement.value; track debt) {
{{ debt.from.name }} diff --git a/src/main/frontend/src/app/component/expense/settlement-dialog/settlement-dialog.component.ts b/src/main/frontend/src/app/component/expense/settlement-dialog/settlement-dialog.component.ts index c4eaf2d..b146ebd 100644 --- a/src/main/frontend/src/app/component/expense/settlement-dialog/settlement-dialog.component.ts +++ b/src/main/frontend/src/app/component/expense/settlement-dialog/settlement-dialog.component.ts @@ -13,6 +13,7 @@ import {MatTooltip} from '@angular/material/tooltip'; import {JsonPipe, KeyValuePipe, NgFor, NgIf} from '@angular/common'; import {Settlement} from "../../../model/settlement"; import {MatCheckbox} from "@angular/material/checkbox"; +import {ExpenseService} from "../../../service/expense.service"; @Component({ selector: 'settlement-dialog', @@ -24,6 +25,7 @@ import {MatCheckbox} from "@angular/material/checkbox"; export class SettlementDialogComponent { constructor( public dialogRef: MatDialogRef, + public expenseService: ExpenseService, @Inject(MAT_DIALOG_DATA) public data: SettlementDialogData, ) { console.log(data) @@ -41,6 +43,24 @@ export class SettlementDialogComponent { // return debts.reduce((accumulator, curValue) => accumulator + curValue.amount, 0) > 0; // } || calculateDebts(data.debts) + calculate(change: boolean) { + if (change) { + Object.keys(this.data.debts) + .filter(currency => currency !== this.data.group.defaultCurrency) + .forEach(currency => { + // Iterate over each transaction in the array for the current currency + this.data.debts[currency].forEach(transaction => { + console.log(`From: ${transaction.from.name}, To: ${transaction.to.name}, Amount: ${transaction.amount}`); + this.expenseService.recalculateForeignCurrency(transaction.amount, currency).subscribe(exchangeRate => { + transaction.amount = +Math.floor(exchangeRate).toFixed(2); + currency = this.data.group.defaultCurrency!; + console.log(`From: ${transaction.from.name}, To: ${transaction.to.name}, Amount: ${transaction.amount}`); + }); + }); + }); + + } + } } export interface SettlementDialogData { diff --git a/src/main/frontend/src/app/service/expense.service.ts b/src/main/frontend/src/app/service/expense.service.ts index ee0247c..8889979 100644 --- a/src/main/frontend/src/app/service/expense.service.ts +++ b/src/main/frontend/src/app/service/expense.service.ts @@ -43,4 +43,13 @@ export class ExpenseService { findById(expenseId: number) { return this.httpClient.get(`${environment.API_URL}/expense/findById/${expenseId}`); } + + recalculateForeignCurrency(amount: number, currency: string) { + return this.httpClient.get(`${environment.API_URL}/expense/recalculateForeignCurrency`, { + params: { + amount, + currency + } + }); + } } diff --git a/src/main/java/pl/janis/komornik/dto/ExchangeRateResponse.java b/src/main/java/pl/janis/komornik/dto/ExchangeRateResponse.java new file mode 100644 index 0000000..91919da --- /dev/null +++ b/src/main/java/pl/janis/komornik/dto/ExchangeRateResponse.java @@ -0,0 +1,9 @@ +package pl.janis.komornik.dto; + +public record ExchangeRateResponse( + String table, + String currency, + String code, + Rate[] rates +) { +} diff --git a/src/main/java/pl/janis/komornik/dto/Rate.java b/src/main/java/pl/janis/komornik/dto/Rate.java new file mode 100644 index 0000000..078a806 --- /dev/null +++ b/src/main/java/pl/janis/komornik/dto/Rate.java @@ -0,0 +1,10 @@ +package pl.janis.komornik.dto; + +import java.math.BigDecimal; + +public record Rate( + String no, + String effectiveDate, + BigDecimal mid +) { +} diff --git a/src/main/java/pl/janis/komornik/rest/ExpenseRestController.java b/src/main/java/pl/janis/komornik/rest/ExpenseRestController.java index 760bcc7..6c45082 100644 --- a/src/main/java/pl/janis/komornik/rest/ExpenseRestController.java +++ b/src/main/java/pl/janis/komornik/rest/ExpenseRestController.java @@ -8,6 +8,7 @@ import pl.janis.komornik.entities.User; import pl.janis.komornik.service.ExpenseService; +import java.math.BigDecimal; import java.security.Principal; import java.util.List; import java.util.Map; @@ -57,5 +58,11 @@ public void deleteExpense(@PathVariable int id) { expenseService.deleteExpense(id); } - + @GetMapping("/recalculateForeignCurrency") + public BigDecimal recalculateForeignCurrency(@RequestParam BigDecimal amount, @RequestParam String currency) { + if (amount != null && currency != null) { + return expenseService.recalculateForeignCurrency(amount, currency); + } + return null; + } } diff --git a/src/main/java/pl/janis/komornik/service/ExpenseService.java b/src/main/java/pl/janis/komornik/service/ExpenseService.java index c3f6d40..973b3a4 100644 --- a/src/main/java/pl/janis/komornik/service/ExpenseService.java +++ b/src/main/java/pl/janis/komornik/service/ExpenseService.java @@ -28,6 +28,7 @@ public class ExpenseService { private final ExpenseMapper expenseMapper; private final UserService userService; private final GroupService groupService; + private final NBPExchangeService nbpExchangeService; public ExpenseDto findById(int id) { return expenseMapper.toDto(expenseRepository.findById(id).orElseThrow(() -> new ElementDoesNotExistException("No results"))); @@ -121,4 +122,8 @@ public ExpenseDto saveExpense(ExpenseDto expenseDto, User currentUser) { final Expense expense = expenseMapper.toEntity(expenseDto); return expenseMapper.toDto(expenseRepository.save(expense)); } + + public BigDecimal recalculateForeignCurrency(BigDecimal amount, String currency) { + return nbpExchangeService.getExchangeRate(amount, currency); + } } diff --git a/src/main/java/pl/janis/komornik/service/NBPExchangeService.java b/src/main/java/pl/janis/komornik/service/NBPExchangeService.java new file mode 100644 index 0000000..0e9ee0b --- /dev/null +++ b/src/main/java/pl/janis/komornik/service/NBPExchangeService.java @@ -0,0 +1,25 @@ +package pl.janis.komornik.service; + +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; +import pl.janis.komornik.dto.ExchangeRateResponse; + +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; + +@Service +public class NBPExchangeService { + + public BigDecimal getExchangeRate(BigDecimal amount, String currency) { + LocalDate today = LocalDate.now(); + String formattedDate = today.format(DateTimeFormatter.ISO_LOCAL_DATE); + String url = String.format("https://api.nbp.pl/api/exchangerates/rates/a/%s/%s/?format=json", currency, formattedDate); + RestTemplate restTemplate = new RestTemplate(); + ExchangeRateResponse result = restTemplate.getForObject(url, ExchangeRateResponse.class); + if (result != null) { + return result.rates()[0].mid().multiply(amount); + } + return BigDecimal.ONE; + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index a48b258..894f9f6 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -8,4 +8,5 @@ spring.mail.properties.mail.smtp.starttls.enable=true spring.banner.location=classpath:banner.txt jwt.duration=1 jwt.secret-key=ENC(cD/Zb7b/kxjvWeMmk1ka+AUkCZOeKfx+UJvxQnC6eGv16N4hNjZhj8gAJ5uluJZ4NlrFY+uQzSA0+1OKDa9AZaSpuKOujChmAoUhpnK93iJ4Bh2FGoQYvgXG0M/QkaAV5XQetJeHX1FZZV/IPaHIzWiBps3mc/rf72NdZaHmyrKQhVcSP6NKY5c4a/o94auV) -spring.config.import=classpath:application-secrets.properties \ No newline at end of file +spring.config.import=classpath:application-secrets.properties +spring.threads.virtual.enabled=true \ No newline at end of file