diff --git a/CHANGELOG.md b/CHANGELOG.md index f9de4cb5a..109beacbb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Upgraded `fuse.js` from version `7.3.0` to `7.5.0` +### Fixed + +- Resolved an exception in the `POST api/v1/activities` endpoint when creating an activity with the update account balance option but without an account + ## 3.33.0 - 2026-07-25 ### Added diff --git a/apps/api/src/app/account/account.service.ts b/apps/api/src/app/account/account.service.ts index f84f085a3..209806234 100644 --- a/apps/api/src/app/account/account.service.ts +++ b/apps/api/src/app/account/account.service.ts @@ -37,11 +37,26 @@ export class AccountService { public async account({ id_userId }: Prisma.AccountWhereUniqueInput): Promise { - const [account] = await this.accounts({ - where: id_userId + const account = await this.prismaService.account.findUnique({ + include: { + balances: { + orderBy: { date: 'desc' }, + take: 1 + } + }, + where: { id_userId } }); - return account; + if (!account) { + return null; + } + + const { balances, ...accountData } = account; + + return { + ...accountData, + balance: balances[0]?.value ?? 0 + }; } public async accountWithActivities( diff --git a/apps/api/src/app/activities/activities.service.ts b/apps/api/src/app/activities/activities.service.ts index 459293abd..fbe93d9a0 100644 --- a/apps/api/src/app/activities/activities.service.ts +++ b/apps/api/src/app/activities/activities.service.ts @@ -275,7 +275,7 @@ export class ActivitiesService { include: { SymbolProfile: true } }); - if (updateAccountBalance === true) { + if (accountId && updateAccountBalance === true) { let amount = new Big(data.unitPrice).mul(data.quantity); if (['BUY', 'FEE'].includes(data.type)) { diff --git a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts index 79e1e8983..632db1cd4 100644 --- a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts +++ b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts @@ -266,16 +266,9 @@ export class GfCreateOrUpdateActivityDialogComponent { this.activityForm.get('currency')?.setValue(currency); this.activityForm.get('currencyOfUnitPrice')?.setValue(currency); - - if (['FEE', 'INTEREST'].includes(type)) { - if (this.activityForm.get('accountId')?.value) { - this.activityForm.get('updateAccountBalance')?.enable(); - } else { - this.activityForm.get('updateAccountBalance')?.disable(); - this.activityForm.get('updateAccountBalance')?.setValue(false); - } - } } + + this.syncUpdateAccountBalanceControl(); }); this.activityForm @@ -299,12 +292,7 @@ export class GfCreateOrUpdateActivityDialogComponent { }); this.activityForm.get('date')?.valueChanges.subscribe(() => { - if (isToday(this.activityForm.get('date')?.value)) { - this.activityForm.get('updateAccountBalance')?.enable(); - } else { - this.activityForm.get('updateAccountBalance')?.disable(); - this.activityForm.get('updateAccountBalance')?.setValue(false); - } + this.syncUpdateAccountBalanceControl(); this.changeDetectorRef.markForCheck(); }); @@ -384,8 +372,6 @@ export class GfCreateOrUpdateActivityDialogComponent { .get('searchSymbol') ?.removeValidators(Validators.required); this.activityForm.get('searchSymbol')?.updateValueAndValidity(); - this.activityForm.get('updateAccountBalance')?.disable(); - this.activityForm.get('updateAccountBalance')?.setValue(false); } else if (['FEE', 'INTEREST', 'LIABILITY'].includes(type)) { const currency = this.data.accounts.find(({ id }) => { @@ -421,16 +407,6 @@ export class GfCreateOrUpdateActivityDialogComponent { if (type === 'FEE') { this.activityForm.get('unitPrice')?.setValue(0); } - - if ( - ['FEE', 'INTEREST'].includes(type) && - this.activityForm.get('accountId')?.value - ) { - this.activityForm.get('updateAccountBalance')?.enable(); - } else { - this.activityForm.get('updateAccountBalance')?.disable(); - this.activityForm.get('updateAccountBalance')?.setValue(false); - } } else { this.activityForm .get('dataSource') @@ -442,9 +418,10 @@ export class GfCreateOrUpdateActivityDialogComponent { .get('searchSymbol') ?.setValidators(Validators.required); this.activityForm.get('searchSymbol')?.updateValueAndValidity(); - this.activityForm.get('updateAccountBalance')?.enable(); } + this.syncUpdateAccountBalanceControl(); + this.changeDetectorRef.markForCheck(); }); @@ -559,6 +536,27 @@ export class GfCreateOrUpdateActivityDialogComponent { } } + private syncUpdateAccountBalanceControl() { + const accountBalanceControl = this.activityForm.get('updateAccountBalance'); + const accountId = this.activityForm.get('accountId')?.value; + const dataSource = this.activityForm.get('dataSource')?.value; + const date = this.activityForm.get('date')?.value; + const type = this.activityForm.get('type')?.value; + + const isEligible = + !!accountId && + isToday(date) && + !['LIABILITY', 'VALUABLE'].includes(type) && + !(dataSource === 'MANUAL' && type === 'BUY'); + + if (isEligible) { + accountBalanceControl?.enable(); + } else { + accountBalanceControl?.disable(); + accountBalanceControl?.setValue(false); + } + } + private updateAssetProfile() { this.isLoading = true; this.changeDetectorRef.markForCheck();