update sth :)

This commit is contained in:
2024-11-26 17:55:34 +07:00
parent 8b01df2111
commit 1062f5944d
4 changed files with 52 additions and 25 deletions

View File

@@ -1,11 +1,6 @@
import { Inject, Injectable } from '@nestjs/common' import { Inject, Injectable } from '@nestjs/common'
import { OrderStatus, Prisma, Role, ServiceStatus } from '@prisma/client' import { OrderStatus, Prisma, Role, ServiceStatus } from '@prisma/client'
import { import { Pothos, PothosRef, PothosSchema, SchemaBuilderToken } from '@smatch-corp/nestjs-pothos'
Pothos,
PothosRef,
PothosSchema,
SchemaBuilderToken,
} from '@smatch-corp/nestjs-pothos'
import { DateTimeUtils } from 'src/common/utils/datetime.utils' import { DateTimeUtils } from 'src/common/utils/datetime.utils'
import { Builder } from 'src/Graphql/graphql.builder' import { Builder } from 'src/Graphql/graphql.builder'
import { PrismaService } from 'src/Prisma/prisma.service' import { PrismaService } from 'src/Prisma/prisma.service'
@@ -125,6 +120,12 @@ export class AnalyticSchema extends PothosSchema {
totalMentorCount: t.int({ totalMentorCount: t.int({
description: 'The total number of mentors.', description: 'The total number of mentors.',
}), }),
totalServiceCount: t.int({
description: 'The total number of services.',
}),
totalWorkshopCount: t.int({
description: 'The total number of workshops.',
}),
revenue: t.int({ revenue: t.int({
description: 'The total revenue.', description: 'The total revenue.',
}), }),
@@ -172,8 +173,7 @@ export class AnalyticSchema extends PothosSchema {
resolve: async (_parent, _args, ctx, _info) => { resolve: async (_parent, _args, ctx, _info) => {
if (ctx.isSubscription) throw new Error('Not allowed') if (ctx.isSubscription) throw new Error('Not allowed')
if (!ctx.http.me) throw new Error('Unauthorized') if (!ctx.http.me) throw new Error('Unauthorized')
if (ctx.http.me.role !== Role.CUSTOMER) if (ctx.http.me.role !== Role.CUSTOMER) throw new Error('Only customers can access this data')
throw new Error('Only customers can access this data')
// calculate analytic // calculate analytic
const activeServiceCount = await this.prisma.order.count({ const activeServiceCount = await this.prisma.order.count({
where: { where: {
@@ -219,8 +219,7 @@ export class AnalyticSchema extends PothosSchema {
resolve: async (_parent, _args, ctx, _info) => { resolve: async (_parent, _args, ctx, _info) => {
if (ctx.isSubscription) throw new Error('Not allowed') if (ctx.isSubscription) throw new Error('Not allowed')
if (!ctx.http.me) throw new Error('Unauthorized') if (!ctx.http.me) throw new Error('Unauthorized')
if (ctx.http.me.role !== Role.CENTER_MENTOR) if (ctx.http.me.role !== Role.CENTER_MENTOR) throw new Error('Only center mentors can access this data')
throw new Error('Only center mentors can access this data')
// calculate analytic // calculate analytic
return { return {
userId: ctx.http.me.id, userId: ctx.http.me.id,
@@ -233,8 +232,7 @@ export class AnalyticSchema extends PothosSchema {
resolve: async (_parent, _args, ctx, _info) => { resolve: async (_parent, _args, ctx, _info) => {
if (ctx.isSubscription) throw new Error('Not allowed') if (ctx.isSubscription) throw new Error('Not allowed')
if (!ctx.http.me) throw new Error('Unauthorized') if (!ctx.http.me) throw new Error('Unauthorized')
if (ctx.http.me.role !== Role.CENTER_OWNER) if (ctx.http.me.role !== Role.CENTER_OWNER) throw new Error('Only center owners can access this data')
throw new Error('Only center owners can access this data')
// get center by owner id // get center by owner id
const center = await this.prisma.center.findUnique({ const center = await this.prisma.center.findUnique({
where: { where: {
@@ -281,8 +279,7 @@ export class AnalyticSchema extends PothosSchema {
}) })
if (!service) continue if (!service) continue
const commission = service.commission const commission = service.commission
const actualRevenue = const actualRevenue = (order.total || 0) - (order.total || 0) * commission
(order.total || 0) - (order.total || 0) * commission
revenue += actualRevenue revenue += actualRevenue
} }
return { return {
@@ -323,10 +320,7 @@ export class AnalyticSchema extends PothosSchema {
resolve: async (_parent, args, ctx, _info) => { resolve: async (_parent, args, ctx, _info) => {
if (ctx.isSubscription) throw new Error('Not allowed') if (ctx.isSubscription) throw new Error('Not allowed')
if (!ctx.http.me) throw new Error('Unauthorized') if (!ctx.http.me) throw new Error('Unauthorized')
if ( if (ctx.http.me.role !== Role.ADMIN && ctx.http.me.role !== Role.MODERATOR)
ctx.http.me.role !== Role.ADMIN &&
ctx.http.me.role !== Role.MODERATOR
)
throw new Error('Only admins and moderators can access this data') throw new Error('Only admins and moderators can access this data')
// calculate analytic for services sorted by args.serviceSortBy and args.timeframes // calculate analytic for services sorted by args.serviceSortBy and args.timeframes
const topServices = await this.prisma.service.findMany({ const topServices = await this.prisma.service.findMany({
@@ -411,13 +405,17 @@ export class AnalyticSchema extends PothosSchema {
status: ServiceStatus.REJECTED, status: ServiceStatus.REJECTED,
}, },
}) })
// get total workshop count
const totalWorkshopCount = await this.prisma.workshop.count()
// get total order count
const totalOrderCount = await this.prisma.order.count()
// get total service count
const totalServiceCount = await this.prisma.service.count()
// get revenue // get revenue
let revenue = 0 let revenue = 0
// query all orders of services in all centers in the past args.timeframes and calculate actual revenue of each order by convert commission percentage to float // query all orders of services in all centers in the past args.timeframes and calculate actual revenue of each order by convert commission percentage to float
// convert args.timeframes to number of days // convert args.timeframes to number of days
const timeframes = DateTimeUtils.subtractDaysFromTimeframe( const timeframes = DateTimeUtils.subtractDaysFromTimeframe(args.timeframes)
args.timeframes,
)
const orders = await this.prisma.order.findMany({ const orders = await this.prisma.order.findMany({
where: { where: {
status: OrderStatus.PAID, status: OrderStatus.PAID,
@@ -432,8 +430,7 @@ export class AnalyticSchema extends PothosSchema {
}) })
if (!service) continue if (!service) continue
const commission = service.commission const commission = service.commission
const actualRevenue = const actualRevenue = (order.total || 0) - (order.total || 0) * commission
(order.total || 0) - (order.total || 0) * commission
revenue += actualRevenue revenue += actualRevenue
} }
// return analytic // return analytic
@@ -449,6 +446,9 @@ export class AnalyticSchema extends PothosSchema {
revenue: revenue, revenue: revenue,
approvedServiceCount: approvedServiceCount, approvedServiceCount: approvedServiceCount,
rejectedServiceCount: rejectedServiceCount, rejectedServiceCount: rejectedServiceCount,
totalWorkshopCount: totalWorkshopCount,
totalOrderCount: totalOrderCount,
totalServiceCount: totalServiceCount,
updatedAt: DateTimeUtils.now(), updatedAt: DateTimeUtils.now(),
} }
}, },

View File

@@ -5,4 +5,5 @@ export enum DocumentEvent {
PAGE_CREATED = 'document_page_created', PAGE_CREATED = 'document_page_created',
PAGE_DELETED = 'document_page_deleted', PAGE_DELETED = 'document_page_deleted',
ACTIVE_DOCUMENT_ID_CHANGED = 'document_active_document_id_changed', ACTIVE_DOCUMENT_ID_CHANGED = 'document_active_document_id_changed',
REQUEST_SYNC = 'document_request_sync',
} }

View File

@@ -204,7 +204,7 @@ export class DocumentSchema extends PothosSchema {
}, },
}), }),
eventUpdateDocument: t.field({ eventDocumentChanged: t.field({
type: this.documentDelta(), type: this.documentDelta(),
args: { args: {
data: t.arg({ data: t.arg({
@@ -226,6 +226,23 @@ export class DocumentSchema extends PothosSchema {
return args.data return args.data
}, },
}), }),
eventDocumentRequestSync: t.field({
type: this.documentDelta(),
args: {
data: t.arg({
type: this.documentDeltaInput(),
required: true,
}),
},
resolve: async (_, args, ctx: SchemaContext) => {
if (ctx.isSubscription) throw new Error('Not allowed')
return {
...args.data,
senderId: ctx.http?.me?.id,
eventType: DocumentEvent.REQUEST_SYNC,
}
},
}),
updateDocument: t.prismaField({ updateDocument: t.prismaField({
type: this.document(), type: this.document(),

View File

@@ -3,6 +3,7 @@ import { Pothos, PothosRef, PothosSchema, SchemaBuilderToken } from '@smatch-cor
import { Builder } from '../Graphql/graphql.builder' import { Builder } from '../Graphql/graphql.builder'
import { PrismaService } from '../Prisma/prisma.service' import { PrismaService } from '../Prisma/prisma.service'
import { OrderStatus, PaymentStatus, RefundTicketStatus, Role } from '@prisma/client' import { OrderStatus, PaymentStatus, RefundTicketStatus, Role } from '@prisma/client'
import { DateTimeUtils } from 'src/common/utils/datetime.utils'
@Injectable() @Injectable()
export class RefundTicketSchema extends PothosSchema { export class RefundTicketSchema extends PothosSchema {
@@ -107,12 +108,20 @@ export class RefundTicketSchema extends PothosSchema {
if (!order.total || order.total === 0) { if (!order.total || order.total === 0) {
throw new Error('Order total is null or free') throw new Error('Order total is null or free')
} }
// calculate refund amount based on order time: if order is less than 24 hours, refund 100%, if more than 24 hours, less than 48 hours, refund 50%, if more than 72 hours, cannot refund
const now = DateTimeUtils.now()
const orderDate = DateTimeUtils.fromDate(order.createdAt)
const diffTime = Math.abs(now.diff(orderDate).toMillis())
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24))
let refundAmount = 0
if (diffDays < 24) refundAmount = order.total
else if (diffDays < 48) refundAmount = order.total * 0.5
// create refund ticket // create refund ticket
const refundTicket = await this.prisma.refundTicket.create({ const refundTicket = await this.prisma.refundTicket.create({
data: { data: {
orderId: order.id, orderId: order.id,
status: RefundTicketStatus.PENDING, status: RefundTicketStatus.PENDING,
amount: order.total, amount: refundAmount,
}, },
}) })
return refundTicket return refundTicket