Skip to content

Commit

Permalink
#19 getMatchingRoundIdForGrantsを利用しようしてmoduleをimportするあたりで完全にハマった
Browse files Browse the repository at this point in the history
  • Loading branch information
tkgshn committed May 4, 2024
1 parent efb6134 commit eb35a59
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 76 deletions.
118 changes: 48 additions & 70 deletions backend/src/provider/adapter/stripe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@ import {
HttpStatus,
Logger,
LoggerService,
Injectable,
} from '@nestjs/common';
import {
FeeAllocationMethod,
SuccessfulCheckoutInfo,
} from '../provider.interface';
import { PoolWithFunding } from 'src/pool/pool.interface';
import { QfService } from 'src/qf/qf.service';
import { QfService } from 'src/qf/qf.service'; // QfServiceをインポート

export interface PaymentIntentEventWebhookBody {
id: string;
Expand Down Expand Up @@ -87,24 +88,29 @@ export interface PaymentIntentEventWebhookBody {
type: string;
}

@Injectable()
export class StripeProvider implements PaymentProviderAdapter {

// private qfService: QfService; // QfServiceのプロパティを追加

constructor(constructorProps: PaymentProviderConstructorProps) {
const { prisma, secret, country } = constructorProps;
const { prisma, secret, country, qfService } = constructorProps;

this.prisma = prisma;
this.country = country;
this.stripe = new Stripe(secret, {
apiVersion: '2022-11-15',
});
this.qfService = this.qfService; // QfService を初期化
this.qfService = qfService; // QfServiceを初期化
}

private prisma: PrismaService;
private country: string;
private stripe: Stripe;
private logger: LoggerService = new Logger(StripeProvider.name);
// Technically a payment provider should never be updated during runtime
// so we can save and cache information about the payment provider in the class itself
private qfService: QfService; // QfService を追加
private qfService: QfService;

/**
* Rounds a number to two decimal places
Expand Down Expand Up @@ -196,31 +202,13 @@ export class StripeProvider implements PaymentProviderAdapter {




// const qfAmounts = await this.qfService.calculateQuadraticFundingAmount(matchingRoundId);

// // MatchedFundテーブルに上乗せ金額を保存
// await this.saveMatchedFunds(qfAmounts, matchingRoundId);

for await (const grant of grantWithFunding) {
if (grant.amount > 0) {
// const checkout = await this.prisma.checkout.create({
// data: {
// user: {
// connect: {
// id: user.id,
// },
// },
// amount: grantAmountLookup[grant.id],
// denomination: provider.denominations[0],
// grant: {
// connect: {
// id: grant.id,
// },
// },
// groupId: transferGroup,
// },
// });

// Contribution テーブルにデータを保存
await this.prisma.contribution.create({
Expand All @@ -237,42 +225,46 @@ export class StripeProvider implements PaymentProviderAdapter {
},
});

// const qfAmount = await this.qfService.calculateQuadraticFundingAmount(matchingRoundId);

// `MatchedFund`テーブルを検索し、すでに同じgrantIdがあるかどうかを判定
const existingMatchedFund = await this.prisma.matchedFund.findUnique({
where: {
matchingRoundId_grantId: {
matchingRoundId: matchingRoundId, // このマッチングラウンドIDを取得する必要があります
grantId: grant.id,
},
},
});

if (existingMatchedFund) {
// 既存のレコードが見つかった場合、amountを更新
await this.prisma.matchedFund.update({
where: {
id: existingMatchedFund.id,
},
data: {
amount: existingMatchedFund.amount + 10,
amountUsd: existingMatchedFund.amount + 10,
},
});
} else {
// レコードが存在しない場合、MatchedFundテーブルにデータを保存する
await this.prisma.matchedFund.create({
data: {
matchingRoundId: matchingRoundId, //matchingRoundId関数は寄付したプロジェクトが属しているマッチングラウンドのIDを返す
grantId: grant.id, // 寄付したプロジェクトのgrantId
amount: 10000, //本来は、上乗せ金額を計算して入れる
denomination: "JPY", //固定
amountUsd: 10000, //
payoutAt: new Date(),
},
});
}
// // `MatchedFund`テーブルを検索し、すでに同じgrantIdがあるかどうかを判定
// const existingMatchedFund = await this.prisma.matchedFund.findUnique({
// where: {
// matchingRoundId_grantId: {
// matchingRoundId: matchingRoundId, // このマッチングラウンドIDを取得する必要があります
// grantId: grant.id,
// },
// },
// });

// if (existingMatchedFund) {
// // 既存のレコードが見つかった場合、amountを更新
// await this.prisma.matchedFund.update({
// where: {
// id: existingMatchedFund.id,
// },
// data: {
// amount: qfAmount.grants[grant.id].qfAmount,
// amountUsd: qfAmount.grants[grant.id].qfAmount,
// },
// });
// } else {
// // レコードが存在しない場合、MatchedFundテーブルにデータを保存する
// await this.prisma.matchedFund.create({
// data: {
// matchingRoundId: matchingRoundId, //matchingRoundId関数は寄付したプロジェクトが属しているマッチングラウンドのIDを返す
// grantId: grant.id, // 寄付したプロジェクトのgrantId
// amount: qfAmount.grants[grant.id].qfAmount, //本来は、上乗せ金額を計算して入れる
// denomination: "JPY", //固定
// amountUsd: qfAmount.grants[grant.id].qfAmount, //
// payoutAt: new Date(),
// },
// });
// }

// 寄付が行われた際に呼び出される関数内で以下の処理を追加
await this.qfService.handleMatchedFunds(matchingRoundId, grant.id); //Cannot read properties of undefined (reading 'handleMatchedFunds')というエラーが出てる


}
Expand Down Expand Up @@ -327,21 +319,6 @@ export class StripeProvider implements PaymentProviderAdapter {
return session;
}

// // 上乗せ金額をMatchedFundテーブルに保存するメソッド
// async saveMatchedFunds(qfAmounts, matchingRoundId) {
// const matchedFundsData = qfAmounts.map((amount, grantId) => ({
// matchingRoundId: matchingRoundId,
// grantId: grantId,
// amount: amount,
// denomination: 'JPY', // 通貨はJPYに固定
// amountUsd: amount, // USD換算が必要な場合はここを調整
// payoutAt: new Date(), // 支払われる日付、必要に応じて調整
// }));

// await this.prisma.matchedFund.createMany({
// data: matchedFundsData,
// });
// }

// // 与えられたグラントに対応するマッチングラウンドIDを取得するメソッド
async getMatchingRoundIdForGrants(grantWithFunding: GrantWithFunding[]): Promise<string> {
Expand All @@ -366,6 +343,7 @@ export class StripeProvider implements PaymentProviderAdapter {
}



/**
* Initiate a payment process with Stripe for pools
* @param poolWithFunding
Expand Down
2 changes: 2 additions & 0 deletions backend/src/provider/adapter/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ import {
SuccessfulCheckoutInfo,
} from '../provider.interface';
import { PoolWithFunding } from 'src/pool/pool.interface';
import { QfService } from 'src/qf/qf.service'; // この行を追加

export interface PaymentProviderConstructorProps {
prisma: PrismaService;
secret: string;
/** ISO country code */
country: string;
qfService: QfService; // この行を追加
}

export interface PaymentProviderAdapter {
Expand Down
4 changes: 3 additions & 1 deletion backend/src/provider/provider.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@ import { StripeProvider } from './adapter/stripe';
import { PaymentProviderAdapter } from './adapter/types';
import { PoolWithFunding } from 'src/pool/pool.interface';
import { CheckoutType, FeeAllocationMethod } from './provider.interface';
import { QfService } from 'src/qf/qf.service'; // この行を追加

@Injectable()
export class ProviderService {
constructor(private readonly prisma: PrismaService) {
constructor(private readonly prisma: PrismaService, private readonly qfService: QfService) {
this.paymentProvider = new StripeProvider({
prisma,
secret: process.env.PAYMENT_KEY,
country: 'JP',
qfService, // この行を追加
});
}
private paymentProvider: PaymentProviderAdapter;
Expand Down
4 changes: 4 additions & 0 deletions backend/src/qf/qf.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,7 @@ export interface PoolMatchInformation {
sumOfQfValues: number;
totalFundsInPool: number;
}

export interface handleMatchedFunds {
matchedFunds: MatchedFund[];
}
14 changes: 11 additions & 3 deletions backend/src/qf/qf.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,20 @@ import { Module } from '@nestjs/common';
import { QfService } from './qf.service';
import { PrismaModule } from 'src/prisma/prisma.module';
import { QfController } from './qf.controller';
import { PrismaService } from 'src/prisma/prisma.service';
import { ProviderService } from 'src/provider/provider.service';
import { ProviderModule } from 'src/provider/provider.module';

// @Module({
// imports: [PrismaModule, ProviderModule],
// providers: [QfService, PrismaService, ProviderModule],
// exports: [QfService, PrismaService, ProviderModule],
// controllers: [QfController],
// })
@Module({
imports: [PrismaModule, ProviderModule],
providers: [QfService],
exports: [QfService],
imports: [PrismaModule, ProviderModule], // ProviderModule をインポート
providers: [QfService, PrismaService], // PrismaService をプロバイダーに追加
exports: [QfService, PrismaService], // PrismaService をエクスポート
controllers: [QfController],
})
export class QfModule {}
42 changes: 41 additions & 1 deletion backend/src/qf/qf.service.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { Injectable, Logger, LoggerService } from '@nestjs/common';
import { PrismaService } from 'src/prisma/prisma.service';
import { PoolMatchInformation, PoolQfInformation } from './qf.interface';
import { PoolMatchInformation, PoolQfInformation, handleMatchedFunds } from './qf.interface';
import { Cron, CronExpression } from '@nestjs/schedule';
import { ProviderService } from 'src/provider/provider.service';
// import { ProviderModule } from 'src/provider/provider.module';
// import { PrismaModule } from 'src/prisma/prisma.module';


@Injectable()
export class QfService {
Expand Down Expand Up @@ -263,4 +266,41 @@ export class QfService {
}
}
}

async handleMatchedFunds(matchingRoundId: string, grantId: string) {
const qfResult = await this.calculateQuadraticFundingAmount(matchingRoundId); //MatchingRoundのデータを渡すと、それぞれのプロジェクトに対する上乗せ金額を計算して返す
const matchedAmount = qfResult.grants[grantId].qfAmount;// 上で計算した「qfRest」の中から、特定のプロジェクトの上乗せ金額だけを取得

const existingMatchedFund = await this.prismaService.matchedFund.findUnique({
where: {
matchingRoundId_grantId: {
matchingRoundId: matchingRoundId,
grantId: grantId,
},
},
});

if (existingMatchedFund) {
await this.prismaService.matchedFund.update({
where: {
id: existingMatchedFund.id,
},
data: {
amount: matchedAmount,
amountUsd: matchedAmount,
},
});
} else {
await this.prismaService.matchedFund.create({
data: {
matchingRoundId: matchingRoundId,
grantId: grantId,
amount: matchedAmount,
denomination: "JPY",
amountUsd: matchedAmount,
payoutAt: new Date(),
},
});
}
}
}
2 changes: 1 addition & 1 deletion backend/test/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ const invitesService = {
const qfService = {
getActiveMatchingRoundByGrant: jest.fn().mockResolvedValue(matchingRound),
// estimateMatchedAmount: jest.fn().mockResolvedValue(), // TODO
// calculateQuadraticFundingAmount: jest.fn().mockResolvedValue(), // TODO
calculateQuadraticFundingAmount: jest.fn().mockResolvedValue(matchingRound), // TODO
// distributeMatchedFunds: jest.fn().mockResolvedValue(null), // TODO
};

Expand Down
11 changes: 11 additions & 0 deletions backend/types/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// import { PrismaService } from 'src/prisma/prisma.service';

// import { QfService } from 'src/qf/qf.service'; // QfServiceをインポート

// export interface PaymentProviderConstructorProps {
// prisma: PrismaService;
// secret: string;
// /** ISO country code */
// country: string;
// qfService: QfService; // QfServiceの型を追加
// }

0 comments on commit eb35a59

Please sign in to comment.