diff --git a/apps/api/src/app/admin/admin.service.ts b/apps/api/src/app/admin/admin.service.ts
index 948616d6c..cb2cc897d 100644
--- a/apps/api/src/app/admin/admin.service.ts
+++ b/apps/api/src/app/admin/admin.service.ts
@@ -573,10 +573,77 @@ export class AdminService {
)
]);
+ // Apply field updates after renaming
+ const finalDataSource = DataSource[newDataSource.toString()];
+ const symbolProfileOverrides = {
+ assetClass: assetClass as AssetClass,
+ assetSubClass: assetSubClass as AssetSubClass,
+ countries: countries as Prisma.JsonArray,
+ name: name as string,
+ sectors: sectors as Prisma.JsonArray,
+ url: url as string
+ };
+
+ // Check if we need to delete SymbolProfileOverrides when converting to MANUAL
+ let deleteOverrides = false;
+ if (finalDataSource === 'MANUAL') {
+ const renamedProfile =
+ await this.prismaService.symbolProfile.findFirst({
+ where: {
+ dataSource: finalDataSource,
+ symbol: newSymbol as string
+ },
+ select: {
+ SymbolProfileOverrides: true
+ }
+ });
+
+ deleteOverrides = !!renamedProfile?.SymbolProfileOverrides;
+ }
+
+ const updatedSymbolProfile: Prisma.SymbolProfileUpdateInput = {
+ comment,
+ currency,
+ holdings,
+ isActive,
+ scraperConfiguration,
+ symbolMapping,
+ ...(finalDataSource === 'MANUAL'
+ ? {
+ assetClass,
+ assetSubClass,
+ countries,
+ name,
+ sectors,
+ url,
+ ...(deleteOverrides && {
+ SymbolProfileOverrides: {
+ delete: true
+ }
+ })
+ }
+ : {
+ SymbolProfileOverrides: {
+ upsert: {
+ create: symbolProfileOverrides,
+ update: symbolProfileOverrides
+ }
+ }
+ })
+ };
+
+ await this.symbolProfileService.updateSymbolProfile(
+ {
+ dataSource: finalDataSource,
+ symbol: newSymbol as string
+ },
+ updatedSymbolProfile
+ );
+
const [updatedAssetProfile] =
await this.symbolProfileService.getSymbolProfiles([
{
- dataSource: DataSource[newDataSource.toString()],
+ dataSource: finalDataSource,
symbol: newSymbol as string
}
]);
diff --git a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts
index ce997cf27..573bab913 100644
--- a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts
+++ b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts
@@ -74,6 +74,7 @@ import { IonIcon } from '@ionic/angular/standalone';
import {
AssetClass,
AssetSubClass,
+ DataSource,
MarketData,
Prisma,
SymbolProfile
@@ -708,6 +709,56 @@ export class GfAssetProfileDialogComponent implements OnInit {
});
}
+ protected onConvertToManual() {
+ const uuid = crypto.randomUUID();
+
+ this.adminService
+ .patchAssetProfile(
+ {
+ dataSource: this.data.dataSource,
+ symbol: this.data.symbol
+ },
+ {
+ assetClass:
+ this.assetProfileForm.controls.assetClass?.value ?? undefined,
+ assetSubClass:
+ this.assetProfileForm.controls.assetSubClass?.value ?? undefined,
+ countries: JSON.parse(
+ this.assetProfileForm.controls.countries?.value ?? '[]'
+ ) as Prisma.InputJsonArray,
+ dataSource: 'MANUAL' as DataSource,
+ name: this.assetProfileForm.controls.name?.value || undefined,
+ sectors: JSON.parse(
+ this.assetProfileForm.controls.sectors?.value ?? '[]'
+ ) as Prisma.InputJsonArray,
+ symbol: uuid,
+ url: this.assetProfileForm.controls.url?.value || undefined
+ }
+ )
+ .pipe(
+ catchError(() => {
+ this.snackBar.open(
+ $localize`An error occurred while converting to MANUAL.`,
+ undefined,
+ {
+ duration: ms('3 seconds')
+ }
+ );
+
+ return EMPTY;
+ }),
+ takeUntilDestroyed(this.destroyRef)
+ )
+ .subscribe(() => {
+ const newAssetProfileIdentifier = {
+ dataSource: 'MANUAL',
+ symbol: uuid
+ };
+
+ this.dialogRef.close(newAssetProfileIdentifier);
+ });
+ }
+
protected onTestMarketData() {
this.adminService
.testMarketData({
diff --git a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html
index d9a5354e5..3ecd85cde 100644
--- a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html
+++ b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html
@@ -162,6 +162,16 @@
or
+ } @else {