src/security/fund.service.ts
Properties |
|
Methods |
|
constructor(fundModel: Model<FundDocument>)
|
||||||
|
Defined in src/security/fund.service.ts:32
|
||||||
|
Parameters :
|
| catch | ||||
catch(error)
|
||||
|
Defined in src/security/fund.service.ts:329
|
||||
|
Parameters :
Returns :
any
|
| Async create | |||||||||
create(createFundDto: CreateFundDto, email: string)
|
|||||||||
|
Defined in src/security/fund.service.ts:39
|
|||||||||
|
Parameters :
Returns :
Promise<FundDocument>
|
| Async findByIds | |||||
findByIds(undefined: literal type)
|
|||||
|
Defined in src/security/fund.service.ts:52
|
|||||
|
Parameters :
Returns :
Promise<Fund[]>
|
| Async findByIdsAndInstrument | |||||
findByIdsAndInstrument(undefined: literal type)
|
|||||
|
Defined in src/security/fund.service.ts:82
|
|||||
|
Parameters :
Returns :
Promise<FundWithInstrument[]>
|
| Async findFundsByFilter | ||||||
findFundsByFilter(filterFundDto: FilterFundDto)
|
||||||
|
Defined in src/security/fund.service.ts:103
|
||||||
|
Parameters :
Returns :
Promise<FundWithInstrument | []>
|
| Async findOne | ||||||
findOne(id: string)
|
||||||
|
Defined in src/security/fund.service.ts:123
|
||||||
|
Parameters :
Returns :
Promise<FundWithInstrument | LeanDocument>
|
| Async fundFilesUploader | ||||
fundFilesUploader(fund)
|
||||
|
Defined in src/security/fund.service.ts:199
|
||||
|
Parameters :
Returns :
unknown
|
| Async getFundWithUnSignedUrl | ||||||
getFundWithUnSignedUrl(fund: LeanDocument<FundDocument>)
|
||||||
|
Defined in src/security/fund.service.ts:296
|
||||||
|
Parameters :
Returns :
unknown
|
| Async insertInstruments | ||||||
insertInstruments(funds: LeanDocument<FundDocument>[])
|
||||||
|
Defined in src/security/fund.service.ts:168
|
||||||
|
Parameters :
Returns :
Promise<FundWithInstrument[]>
|
| Async update | |||||||||
update(id: string, updateFundDto: UpdateFundDto)
|
|||||||||
|
Defined in src/security/fund.service.ts:133
|
|||||||||
|
Parameters :
Returns :
Promise<FundDocument>
|
| Private Readonly fundWeb3 |
Type : FundWeb3Service
|
Decorators :
@Inject(FundWeb3Service)
|
|
Defined in src/security/fund.service.ts:27
|
| Private Readonly instrumentService |
Type : InstrumentService
|
Decorators :
@Inject(InstrumentService)
|
|
Defined in src/security/fund.service.ts:30
|
| Private Readonly s3Service |
Type : S3Service
|
|
Defined in src/security/fund.service.ts:32
|
import { InstrumentService } from "./instrument.service";
import { LeanDocument, Model } from "mongoose";
import { InjectModel } from "@nestjs/mongoose";
import {
BadRequestException,
Inject,
Injectable,
ServiceUnavailableException,
} from "@nestjs/common";
import type { CreateFundDto } from "./dto/create-fund.dto";
import type { UpdateFundDto } from "./dto/update-fund.dto";
import type { FilterFundDto } from "./dto/filter-fund.dto";
import { FundWeb3Service } from "./fund.web3.service";
import { S3Service } from "src/common/provider/storage/s3";
import { Fund, FundDocument } from "./schemas/fund.schema";
import { decodeBytes32String } from "ethers";
import { FundWithInstrument, InstrumentSubgraphAndDB } from "./fund.interface";
import { uploadCmsFileFields } from "src/common/utils";
import { IFile } from "src/common/interfaces";
@Injectable()
export class FundService {
@Inject(FundWeb3Service)
private readonly fundWeb3: FundWeb3Service;
@Inject(InstrumentService)
private readonly instrumentService: InstrumentService;
private readonly s3Service: S3Service;
constructor(
@InjectModel(Fund.name) private readonly fundModel: Model<FundDocument>,
) {
this.s3Service = new S3Service();
}
async create(
createFundDto: CreateFundDto,
email: string,
): Promise<FundDocument> {
const fundWithFiles = await this.fundFilesUploader({
...createFundDto,
creator: email,
});
const fund = new this.fundModel(fundWithFiles);
await this.fundWeb3.addFund(fund.id, email);
return fund.save();
}
async findByIds({
ids,
filterFundDto,
}: {
ids: string[];
filterFundDto?: FilterFundDto;
}): Promise<Fund[]> {
try {
const { limit, skip, orderDirection, selectors, ...restOfFilter } =
filterFundDto ?? {};
const funds = await this.fundModel
.find(
{ _id: { $in: ids }, ...restOfFilter },
selectors ? selectors.join(" ") : "",
)
.limit(limit)
.skip(skip * limit)
.sort({ created: orderDirection })
.lean()
.exec();
return await Promise.all(
funds.map((fund) => this.getFundWithUnSignedUrl(fund)),
);
} catch (error) {
console.error(error);
throw new BadRequestException("Wrong subscribedFunds Id", {
cause: error,
});
}
}
async findByIdsAndInstrument({
ids,
filterFundDto,
}: {
ids: string[];
filterFundDto?: FilterFundDto;
}): Promise<FundWithInstrument[]> {
try {
const funds = await this.fundModel
.find({ _id: { $in: ids }, ...filterFundDto })
.lean()
.exec();
return await this.insertInstruments(funds);
} catch (error) {
console.error(error);
throw new ServiceUnavailableException({
cause: error,
});
}
}
async findFundsByFilter(
filterFundDto: FilterFundDto,
): Promise<FundWithInstrument | LeanDocument<FundDocument>[]> {
const { limit, skip, orderDirection, selectors, ...restOfFilter } =
filterFundDto ?? {};
const funds: LeanDocument<FundDocument>[] = await this.fundModel
.find(restOfFilter, selectors ? selectors.join(" ") : "")
.limit(limit)
.skip(skip * limit)
.sort({ created: orderDirection })
.lean()
.exec();
return selectors
? await Promise.all(
funds.map((fund) => this.getFundWithUnSignedUrl(fund)),
)
: await this.insertInstruments(funds);
}
async findOne(
id: string,
): Promise<FundWithInstrument | LeanDocument<FundDocument>> {
const fund = await this.fundModel.findById(id).lean().exec();
if (!fund) {
return null;
}
return await this.getFundWithUnSignedUrl(fund);
}
async update(
id: string,
updateFundDto: UpdateFundDto,
): Promise<FundDocument> {
const cmsFields = [];
if (updateFundDto.cmsFields) {
cmsFields.push(...(await uploadCmsFileFields(updateFundDto.cmsFields)));
}
const uploadToS3: Record<string, string> = {};
await Promise.all(
Object.keys(updateFundDto).map(async (propertyKey) => {
if (updateFundDto[propertyKey].base64String) {
uploadToS3[propertyKey] = await this.s3Service.upload(
updateFundDto[propertyKey] as IFile,
`updated-${propertyKey}-${
updateFundDto[propertyKey].originalname.split(".")[0]
}-${new Date().getTime()}.${
updateFundDto[propertyKey].originalname.split(".")[1]
}`,
);
}
}),
);
return await this.fundModel
.findByIdAndUpdate(
id,
{
...updateFundDto,
...uploadToS3,
cmsFields,
},
{ new: true },
)
.exec();
}
async insertInstruments(
funds: LeanDocument<FundDocument>[],
): Promise<FundWithInstrument[]> {
return await Promise.all(
funds.map(async (fund) => {
const fundWithUrl = await this.getFundWithUnSignedUrl(fund);
const [instrumentsSubgraph, instrumentsDb] = await Promise.all([
this.fundWeb3.getInstrumentsByFundId(fund._id.toString()),
this.instrumentService.findAllByFilter({
fundId: fund._id.toString(),
}),
]);
const instruments: InstrumentSubgraphAndDB[] = instrumentsSubgraph.map(
(subgraphInstrument) => {
const dbInstrument = instrumentsDb.find(
(currentInstrument) =>
currentInstrument._id.toString() ===
decodeBytes32String(subgraphInstrument.id),
);
return {
dbInstrument,
subgraphInstrument,
};
},
);
return { ...fundWithUrl, instruments };
}),
);
}
async fundFilesUploader(fund: CreateFundDto & { creator: string }) {
const [
logoFile,
brochureFile,
keyDocumentsFile,
extraDocumentsFile,
partiesFile,
promotionVideoFile,
strategyFile,
performanceFile,
] = await Promise.all([
this.s3Service.upload(
fund.logoFile,
`logo-${
fund.logoFile.originalname.split(".")[0]
}-${new Date().getTime()}-${fund.creator}.${
fund.logoFile.originalname.split(".")[1]
}`,
),
this.s3Service.upload(
fund.brochureFile,
`brochure-${
fund.brochureFile.originalname.split(".")[0]
}-${new Date().getTime()}-${fund.creator}.${
fund.brochureFile.originalname.split(".")[1]
}`,
),
this.s3Service.upload(
fund.keyDocumentsFile,
`keyDocumentsFile-${
fund.keyDocumentsFile.originalname.split(".")[0]
}-${new Date().getTime()}-${fund.creator}.${
fund.keyDocumentsFile.originalname.split(".")[1]
}`,
),
this.s3Service.upload(
fund.extraDocumentsFile,
`extraDocumentsFile-${
fund.extraDocumentsFile.originalname.split(".")[0]
}-${new Date().getTime()}-${fund.creator}.${
fund.extraDocumentsFile.originalname.split(".")[1]
}`,
),
this.s3Service.upload(
fund.partiesFile,
`partiesFile-${
fund.partiesFile.originalname.split(".")[0]
}-${new Date().getTime()}-${fund.creator}.${
fund.partiesFile.originalname.split(".")[1]
}`,
),
this.s3Service.upload(
fund.promotionVideoFile,
`promotionVideoFile-${
fund.promotionVideoFile.originalname.split(".")[0]
}-${new Date().getTime()}-${fund.creator}.${
fund.promotionVideoFile.originalname.split(".")[1]
}`,
),
this.s3Service.upload(
fund.strategy.file,
`strategyDiagram-${
fund.strategy.file.originalname.split(".")[0]
}-${new Date().getTime()}-${fund.creator}.${
fund.strategy.file.originalname.split(".")[1]
}`,
),
this.s3Service.upload(
fund.performance.file,
`performanceFile-${
fund.performance.file.originalname.split(".")[0]
}-${new Date().getTime()}-${fund.creator}.${
fund.performance.file.originalname.split(".")[1]
}`,
),
]);
const fundWithUploadedFiles: Fund = {
...fund,
logoFile,
brochureFile,
keyDocumentsFile,
extraDocumentsFile,
partiesFile,
promotionVideoFile,
strategy: {
submitter: fund.creator,
fileKey: strategyFile,
data: fund.strategy.data,
},
performance: {
submitter: fund.creator,
fileKey: performanceFile,
data: fund.performance.data,
},
};
return fundWithUploadedFiles;
}
async getFundWithUnSignedUrl(fund: LeanDocument<FundDocument>) {
const filesArray = await Promise.all(
Object.keys(fund)
.filter(
(propertyKey) =>
fund[propertyKey].fileKey ||
(String(fund[propertyKey]).includes(".") &&
String(fund[propertyKey]).includes("-")),
)
.map(async (fileOrReportKey) => {
if (fund[fileOrReportKey].fileKey) {
const fileKey = await this.s3Service.getFileByKey(
fund[fileOrReportKey].fileKey,
);
return {
[fileOrReportKey]: {
...fund[fileOrReportKey],
fileKey,
},
};
}
const fileKey = await this.s3Service.getFileByKey(
fund[fileOrReportKey],
);
return { [fileOrReportKey]: fileKey };
}),
);
const filesObject = Object.assign({}, ...filesArray);
return {
...fund,
...filesObject,
};
}
catch(error) {
console.error(error);
return null;
}
}