城市合伙人端的修改(后台)
This commit is contained in:
@@ -3,6 +3,7 @@ import { Prisma } from '@prisma/client';
|
||||
import { PrismaService } from '../../common/prisma/prisma.module';
|
||||
import { serializeBigInt } from '../../common/decorators/current-user.decorator';
|
||||
import { AnalyticsService } from '../analytics/analytics.service';
|
||||
import { PartnerCityService } from '../city-scope/partner-city.service';
|
||||
|
||||
function generateBillNo() {
|
||||
return `PB${Date.now()}${Math.floor(Math.random() * 900 + 100)}`;
|
||||
@@ -13,6 +14,7 @@ export class SettlementService {
|
||||
constructor(
|
||||
private readonly prisma: PrismaService,
|
||||
private readonly analyticsService: AnalyticsService,
|
||||
private readonly partnerCityService: PartnerCityService,
|
||||
) {}
|
||||
|
||||
async createStorePayout(
|
||||
@@ -152,16 +154,13 @@ export class SettlementService {
|
||||
return results;
|
||||
}
|
||||
|
||||
async listPartnerBills(partnerAccountId: bigint) {
|
||||
const account = await this.prisma.partnerAccount.findUniqueOrThrow({
|
||||
where: { id: partnerAccountId },
|
||||
});
|
||||
async listPartnerBills(partnerAccountId: bigint) { const primary = await this.partnerCityService.resolvePrimaryAccount(partnerAccountId);
|
||||
const bills = await this.prisma.partnerBill.findMany({
|
||||
where: { partnerId: account.partnerId },
|
||||
where: { partnerAccountId: primary.id },
|
||||
orderBy: { createdAt: 'desc' },
|
||||
});
|
||||
this.analyticsService.trackPartnerOneSafe(partnerAccountId, 'PARTNER_H5', {
|
||||
partnerId: account.partnerId,
|
||||
partnerAccountId: primary.id,
|
||||
eventName: 'partner_bill_view',
|
||||
extraJson: { count: bills.length },
|
||||
});
|
||||
@@ -178,7 +177,7 @@ export class SettlementService {
|
||||
const pageSize = query.pageSize ?? 20;
|
||||
const where: Prisma.PartnerBillWhereInput = {};
|
||||
if (query.status) where.status = query.status as Prisma.EnumPartnerBillStatusFilter['equals'];
|
||||
if (query.partnerId) where.partnerId = BigInt(query.partnerId);
|
||||
if (query.partnerId) where.partnerAccountId = BigInt(query.partnerId);
|
||||
|
||||
const [items, total] = await Promise.all([
|
||||
this.prisma.partnerBill.findMany({
|
||||
@@ -186,7 +185,7 @@ export class SettlementService {
|
||||
orderBy: { createdAt: 'desc' },
|
||||
skip: (page - 1) * pageSize,
|
||||
take: pageSize,
|
||||
include: { partner: { select: { companyName: true } } },
|
||||
include: { partnerAccount: { select: { companyName: true } } },
|
||||
}),
|
||||
this.prisma.partnerBill.count({ where }),
|
||||
]);
|
||||
@@ -196,20 +195,21 @@ export class SettlementService {
|
||||
async getAdminPartnerBill(id: bigint) {
|
||||
const bill = await this.prisma.partnerBill.findUnique({
|
||||
where: { id },
|
||||
include: { partner: true },
|
||||
include: { partnerAccount: true },
|
||||
});
|
||||
if (!bill) throw new NotFoundException('账单不存在');
|
||||
return serializeBigInt(bill);
|
||||
}
|
||||
|
||||
async generatePartnerBill(body: { partnerId: string; year: number; month: number }) {
|
||||
const partnerId = BigInt(body.partnerId);
|
||||
const partnerAccountId = BigInt(body.partnerId);
|
||||
const primary = await this.partnerCityService.resolvePrimaryAccount(partnerAccountId);
|
||||
const periodStart = new Date(body.year, body.month - 1, 1);
|
||||
const periodEnd = new Date(body.year, body.month, 0, 23, 59, 59, 999);
|
||||
|
||||
const existing = await this.prisma.partnerBill.findFirst({
|
||||
where: {
|
||||
partnerId,
|
||||
partnerAccountId: primary.id,
|
||||
periodStart,
|
||||
status: { not: 'DRAFT' },
|
||||
},
|
||||
@@ -218,31 +218,33 @@ export class SettlementService {
|
||||
throw new BadRequestException('该月账单已确认,不可重复生成');
|
||||
}
|
||||
|
||||
const cities = await this.prisma.commonCity.findMany({
|
||||
where: { partnerId },
|
||||
include: { commissionRule: true },
|
||||
});
|
||||
const cityIds = cities.map((c) => c.id);
|
||||
const defaultOrderRate = cities[0]?.commissionRule?.orderCommissionRate
|
||||
? Number(cities[0].commissionRule.orderCommissionRate)
|
||||
: 0;
|
||||
const defaultRedeemRate = cities[0]?.commissionRule?.redeemCommissionRate
|
||||
? Number(cities[0].commissionRule.redeemCommissionRate)
|
||||
: 0.03;
|
||||
if (!primary.cityId) {
|
||||
throw new BadRequestException('合伙人未绑定开城城市');
|
||||
}
|
||||
|
||||
const orderCommissionRate = Number(primary.orderCommissionRate ?? 0);
|
||||
const redeemCommissionRate = Number(primary.redeemCommissionRate ?? 0.03);
|
||||
|
||||
const orders = await this.prisma.order.findMany({
|
||||
where: {
|
||||
cityId: { in: cityIds },
|
||||
cityId: primary.cityId,
|
||||
payStatus: 'PAID',
|
||||
paidAt: { gte: periodStart, lte: periodEnd },
|
||||
},
|
||||
});
|
||||
const orderCommission = orders.reduce(
|
||||
(sum, o) => sum + Number(o.payAmount) * defaultOrderRate,
|
||||
0,
|
||||
);
|
||||
const orderCommission = orders.reduce((sum, o) => {
|
||||
if (o.partnerAccountIdAtPay) {
|
||||
if (o.partnerAccountIdAtPay !== primary.id) return sum;
|
||||
const rate = o.orderCommissionRateAtPay != null ? Number(o.orderCommissionRateAtPay) : 0;
|
||||
return sum + Number(o.payAmount) * rate;
|
||||
}
|
||||
return sum + Number(o.payAmount) * orderCommissionRate;
|
||||
}, 0);
|
||||
|
||||
const stores = await this.prisma.store.findMany({ where: { partnerId }, select: { id: true } });
|
||||
const stores = await this.prisma.store.findMany({
|
||||
where: { partnerAccountId: primary.id },
|
||||
select: { id: true },
|
||||
});
|
||||
const storeIds = stores.map((s) => s.id);
|
||||
const redeems = await this.prisma.redeemRecord.findMany({
|
||||
where: {
|
||||
@@ -251,14 +253,14 @@ export class SettlementService {
|
||||
},
|
||||
});
|
||||
const redeemCommission = redeems.reduce(
|
||||
(sum, r) => sum + Number(r.amount) * defaultRedeemRate,
|
||||
(sum, r) => sum + Number(r.amount) * redeemCommissionRate,
|
||||
0,
|
||||
);
|
||||
|
||||
const totalAmount = Math.round((orderCommission + redeemCommission) * 100) / 100;
|
||||
|
||||
const draft = await this.prisma.partnerBill.findFirst({
|
||||
where: { partnerId, periodStart, status: 'DRAFT' },
|
||||
where: { partnerAccountId: primary.id, periodStart, status: 'DRAFT' },
|
||||
});
|
||||
|
||||
const bill = draft
|
||||
@@ -269,7 +271,7 @@ export class SettlementService {
|
||||
: await this.prisma.partnerBill.create({
|
||||
data: {
|
||||
billNo: generateBillNo(),
|
||||
partnerId,
|
||||
partnerAccountId: primary.id,
|
||||
periodStart,
|
||||
periodEnd,
|
||||
orderCommission,
|
||||
@@ -310,12 +312,12 @@ export class SettlementService {
|
||||
|
||||
async exportPartnerBills(query: { partnerId?: string; status?: string }) {
|
||||
const where: Prisma.PartnerBillWhereInput = {};
|
||||
if (query.partnerId) where.partnerId = BigInt(query.partnerId);
|
||||
if (query.partnerId) where.partnerAccountId = BigInt(query.partnerId);
|
||||
if (query.status) where.status = query.status as Prisma.EnumPartnerBillStatusFilter['equals'];
|
||||
|
||||
const bills = await this.prisma.partnerBill.findMany({
|
||||
where,
|
||||
include: { partner: { select: { companyName: true } } },
|
||||
include: { partnerAccount: { select: { companyName: true } } },
|
||||
orderBy: { createdAt: 'desc' },
|
||||
});
|
||||
|
||||
@@ -323,7 +325,7 @@ export class SettlementService {
|
||||
const rows = bills.map((b) =>
|
||||
[
|
||||
b.billNo,
|
||||
b.partner.companyName,
|
||||
b.partnerAccount.companyName,
|
||||
b.periodStart.toISOString().slice(0, 10),
|
||||
b.periodEnd.toISOString().slice(0, 10),
|
||||
Number(b.orderCommission),
|
||||
|
||||
Reference in New Issue
Block a user