Browse Source

fix issue #5419

Root Causes

  Issue 1: Import Validation Failure
  - The validateActivities() method (called at apps/api/src/app/import/import.service.ts#L374) validates activities before
  asset profiles from the import file are created in the database (apps/api/src/app/import/import.service.ts#L245)
  - For MANUAL data source, ManualService.getAssetProfile() queries the database, which returns undefined for new profiles
  - Validation at apps/api/src/app/import/import.service.ts#L774 requires assetProfile.name to exist, causing import to fail

  Issue 2: Empty Name Column
  - Even if validation passes, the validateActivities() method only checked for the existence of the name but didn't populate
  it from the import data
  - The asset profile object used for display lacked the complete profile information from the import file

Solution

  Modified apps/api/src/app/import/import.service.ts:

  1. Pass import data to validation (apps/api/src/app/import/import.service.ts#L376)
    - Added assetProfilesWithMarketDataDto parameter to validateActivities() call
  2. Check import data during validation (apps/api/src/app/import/import.service.ts#L755)
    - When asset profile doesn't exist in database (no name), check if it exists in import data
    - If found in import data, merge all asset profile fields (name, currency, assetClass, etc.) into the validation object
    - This ensures the name and other fields are available for display in the UI
  3. Maintain validation rules (apps/api/src/app/import/import.service.ts#L788)
    - Keep existing validation that requires name for non-MANUAL BUY, DIVIDEND, and SELL activities
    - Separate the data population logic from validation logic
pull/5670/head
Sven Günther 4 weeks ago
committed by Thomas Kaul
parent
commit
e93b4644af
  1. 34
      apps/api/src/app/import/import.service.ts
  2. 53
      test/import/ok/penthouse-apartment.json

34
apps/api/src/app/import/import.service.ts

@ -373,6 +373,7 @@ export class ImportService {
const assetProfiles = await this.validateActivities({
activitiesDto,
assetProfilesWithMarketDataDto,
maxActivitiesToImport,
user
});
@ -698,10 +699,12 @@ export class ImportService {
private async validateActivities({
activitiesDto,
assetProfilesWithMarketDataDto,
maxActivitiesToImport,
user
}: {
activitiesDto: Partial<CreateOrderDto>[];
assetProfilesWithMarketDataDto: ImportDataDto['assetProfiles'];
maxActivitiesToImport: number;
user: UserWithSettings;
}) {
@ -749,6 +752,37 @@ export class ImportService {
)?.[symbol]
};
if (!assetProfile?.name) {
const assetProfileInImport = assetProfilesWithMarketDataDto?.find(
(profile) =>
profile.dataSource === dataSource && profile.symbol === symbol
);
if (assetProfileInImport) {
Object.assign(assetProfile, {
assetClass: assetProfileInImport.assetClass,
assetSubClass: assetProfileInImport.assetSubClass,
comment: assetProfileInImport.comment,
countries: assetProfileInImport.countries,
currency: assetProfileInImport.currency ?? assetProfile.currency,
cusip: assetProfileInImport.cusip,
dataSource: assetProfileInImport.dataSource,
figi: assetProfileInImport.figi,
figiComposite: assetProfileInImport.figiComposite,
figiShareClass: assetProfileInImport.figiShareClass,
holdings: assetProfileInImport.holdings,
isActive: assetProfileInImport.isActive,
isin: assetProfileInImport.isin,
name: assetProfileInImport.name,
scraperConfiguration: assetProfileInImport.scraperConfiguration,
sectors: assetProfileInImport.sectors,
symbol: assetProfileInImport.symbol,
symbolMapping: assetProfileInImport.symbolMapping,
url: assetProfileInImport.url
});
}
}
if (
(dataSource !== 'MANUAL' && type === 'BUY') ||
type === 'DIVIDEND' ||

53
test/import/ok/penthouse-apartment.json

@ -0,0 +1,53 @@
{
"meta": {
"date": "2023-02-05T00:00:00.000Z",
"version": "dev"
},
"accounts": [],
"assetProfiles": [
{
"assetClass": null,
"assetSubClass": null,
"comment": null,
"countries": [],
"currency": "USD",
"cusip": null,
"dataSource": "MANUAL",
"figi": null,
"figiComposite": null,
"figiShareClass": null,
"holdings": [],
"isActive": true,
"isin": null,
"marketData": [],
"name": "Penthouse Apartment",
"scraperConfiguration": null,
"sectors": [],
"symbol": "7e91b7d4-1430-4212-8380-289a06c9bbc1",
"symbolMapping": {},
"url": null
}
],
"platforms": [],
"tags": [],
"activities": [
{
"accountId": null,
"comment": null,
"fee": 0,
"quantity": 1,
"type": "BUY",
"unitPrice": 500000,
"currency": "USD",
"dataSource": "MANUAL",
"date": "2022-01-01T00:00:00.000Z",
"symbol": "7e91b7d4-1430-4212-8380-289a06c9bbc1",
"tags": []
}
],
"user": {
"settings": {
"currency": "USD"
}
}
}
Loading…
Cancel
Save