From d28b26629c325b59fb0a8ce6aa51a9d7107fbd16 Mon Sep 17 00:00:00 2001 From: Ruslan Bakiev Date: Mon, 6 Apr 2026 10:58:27 +0700 Subject: [PATCH] Add manager bonus account detail --- src/resolvers.js | 107 +++++++++++++++++++++++++++++++++++++++------ src/schema.graphql | 16 +++++++ 2 files changed, 109 insertions(+), 14 deletions(-) diff --git a/src/resolvers.js b/src/resolvers.js index 334bc31..54b58ba 100644 --- a/src/resolvers.js +++ b/src/resolvers.js @@ -76,6 +76,23 @@ function formatPercent(value) { return Number(value).toFixed(2).replace(/\.?0+$/, ''); } +function mapManagerReferralLink(link) { + return { + id: link.id, + referrerId: link.referrerId, + referrerName: link.referrer.fullName, + referrerEmail: link.referrer.email, + referrerCompanyName: link.referrer.counterpartyProfile?.companyName ?? null, + refereeId: link.refereeId, + refereeName: link.referee.fullName, + refereeEmail: link.referee.email, + refereeCompanyName: link.referee.counterpartyProfile?.companyName ?? null, + createdById: link.createdById, + bonusPercent: Number(link.bonusPercent), + createdAt: link.createdAt, + }; +} + async function createReferralBonusTransaction(prisma, order) { const referralLink = await prisma.referralLink.findFirst({ where: { @@ -728,20 +745,7 @@ export const resolvers = { orderBy: { createdAt: 'desc' }, }); - return links.map((link) => ({ - id: link.id, - referrerId: link.referrerId, - referrerName: link.referrer.fullName, - referrerEmail: link.referrer.email, - referrerCompanyName: link.referrer.counterpartyProfile?.companyName ?? null, - refereeId: link.refereeId, - refereeName: link.referee.fullName, - refereeEmail: link.referee.email, - refereeCompanyName: link.referee.counterpartyProfile?.companyName ?? null, - createdById: link.createdById, - bonusPercent: Number(link.bonusPercent), - createdAt: link.createdAt, - })); + return links.map(mapManagerReferralLink); }, managerBonusBalances: async (_, __, context) => { @@ -801,6 +805,81 @@ export const resolvers = { }); }, + managerBonusAccount: async (_, { userId }, context) => { + const manager = requireManagerAccess(context); + await assertManagerCanAccessUser(context.prisma, manager, userId); + + const [user, links, transactions, pendingWithdrawals] = await Promise.all([ + context.prisma.user.findUnique({ + where: { id: userId }, + include: { + counterpartyProfile: { + select: { + companyName: true, + }, + }, + }, + }), + context.prisma.referralLink.findMany({ + where: { referrerId: userId }, + include: { + referrer: { + include: { + counterpartyProfile: { + select: { + companyName: true, + }, + }, + }, + }, + referee: { + include: { + counterpartyProfile: { + select: { + companyName: true, + }, + }, + }, + }, + }, + orderBy: { createdAt: 'desc' }, + }), + context.prisma.bonusTransaction.findMany({ + where: { userId }, + orderBy: { createdAt: 'desc' }, + }), + context.prisma.rewardWithdrawalRequest.findMany({ + where: { + requesterId: userId, + status: 'PENDING', + }, + orderBy: { createdAt: 'desc' }, + }), + ]); + + if (!user) { + throw new Error('User was not found.'); + } + + const earnedAmount = transactions.reduce((acc, tx) => acc + Number(tx.amount), 0); + const pendingWithdrawalAmount = pendingWithdrawals.reduce((acc, withdrawal) => acc + Number(withdrawal.amount), 0); + + return { + userId: user.id, + email: user.email, + fullName: user.fullName, + companyName: user.counterpartyProfile?.companyName ?? null, + balance: earnedAmount - pendingWithdrawalAmount, + earnedAmount, + pendingWithdrawalAmount, + transactionsCount: transactions.length, + referralsCount: links.length, + referralLinks: links.map(mapManagerReferralLink), + transactions, + pendingWithdrawals, + }; + }, + managerWithdrawalRequests: async (_, { status }, context) => { const manager = requireManagerAccess(context); const managedUsersWhere = await getManagedClientUserWhere(context.prisma, manager); diff --git a/src/schema.graphql b/src/schema.graphql index b813dae..5d340bf 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -327,6 +327,21 @@ type ManagerBonusBalance { transactionsCount: Int! } +type ManagerBonusAccount { + userId: ID! + email: String! + fullName: String! + companyName: String + balance: Float! + earnedAmount: Float! + pendingWithdrawalAmount: Float! + transactionsCount: Int! + referralsCount: Int! + referralLinks: [ManagerReferralLink!]! + transactions: [BonusTransaction!]! + pendingWithdrawals: [RewardWithdrawalRequest!]! +} + type ManagerWithdrawalRequest { id: ID! requesterId: ID! @@ -358,6 +373,7 @@ type Query { managerOrders(status: OrderStatus, customerId: ID): [Order!]! managerReferralLinks: [ManagerReferralLink!]! managerBonusBalances: [ManagerBonusBalance!]! + managerBonusAccount(userId: ID!): ManagerBonusAccount! managerWithdrawalRequests(status: WithdrawalStatus): [ManagerWithdrawalRequest!]! registrationRequests(status: RegistrationStatus): [RegistrationRequest!]! referralStats: ReferralStats!