Files
nademitex_server/dist/agent/agent.service.js
T

363 lines
15 KiB
JavaScript

"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AgentService = void 0;
const common_1 = require("@nestjs/common");
const client_1 = require("@prisma/client");
const prisma_service_1 = require("../prisma/prisma.service");
let AgentService = class AgentService {
prisma;
constructor(prisma) {
this.prisma = prisma;
}
async requireAgent(agentId) {
const agent = await this.prisma.customer.findUnique({
where: { id: agentId },
});
if (!agent || agent.appRole !== client_1.AppUserRole.agent) {
throw new common_1.ForbiddenException('فقط واسطه به این بخش دسترسی دارد');
}
return agent;
}
async getProfile(agentId) {
const agent = await this.requireAgent(agentId);
const [customersCount, ordersCount] = await Promise.all([
this.prisma.customer.count({
where: { assignedAgentId: agentId, isActive: true },
}),
this.prisma.order.count({
where: {
user: { assignedAgentId: agentId },
},
}),
]);
const sales = await this.prisma.order.aggregate({
where: {
user: { assignedAgentId: agentId },
finalAmount: { not: null },
},
_sum: { finalAmount: true },
});
const salesVolume = sales._sum.finalAmount ?? 0;
return {
id: agent.id,
firstName: agent.firstName,
lastName: agent.lastName,
code: agent.agentCode ?? '',
levelLabel: agent.levelLabel ?? 'برنزی',
nextLevelLabel: agent.nextLevelLabel ?? 'نقره‌ای',
pointsToNext: agent.pointsToNext ?? 0,
levelProgress: agent.levelProgress ?? 0,
phone: agent.phone,
customersCount,
ordersCount,
salesVolumeToman: salesVolume,
profitToman: Math.round(salesVolume * 0.1),
periodLabel: '۳۰۰ روز اخیر',
};
}
async listMyCustomers(agentId, q, status) {
await this.requireAgent(agentId);
const where = {
assignedAgentId: agentId,
...(status === 'active' ? { isActive: true } : {}),
...(status === 'inactive' ? { isActive: false } : {}),
...(q
? {
OR: [
{ firstName: { contains: q, mode: 'insensitive' } },
{ lastName: { contains: q, mode: 'insensitive' } },
{ businessName: { contains: q, mode: 'insensitive' } },
{ phone: { contains: q } },
],
}
: {}),
};
const customers = await this.prisma.customer.findMany({
where,
orderBy: { createdAt: 'desc' },
include: {
orders: {
select: { finalAmount: true, id: true },
},
},
});
return customers.map((c) => {
const amounts = c.orders
.map((o) => o.finalAmount ?? 0)
.filter((n) => n > 0);
const total = amounts.reduce((a, b) => a + b, 0);
const orderCount = c.orders.length;
return {
id: c.id,
name: c.businessName || `${c.firstName} ${c.lastName}`,
contactName: `${c.firstName} ${c.lastName}`,
phone: c.phone,
status: !c.isActive ? 'inactive' : orderCount === 0 ? 'new' : 'active',
avatarLetter: c.avatarLetter || c.firstName.charAt(0),
avatarColor: c.avatarColor || '#c4b5fd',
totalPurchaseToman: total,
orderCount,
averageOrderToman: orderCount ? Math.round(total / orderCount) : 0,
levelLabel: c.levelLabel || 'برنزی',
firstPurchaseDate: '—',
agentCode: undefined,
agentName: undefined,
};
});
}
async getCustomerDetail(agentId, customerId) {
await this.requireAgent(agentId);
const customer = await this.prisma.customer.findFirst({
where: { id: customerId, assignedAgentId: agentId },
include: {
orders: {
orderBy: { createdAt: 'desc' },
take: 20,
},
},
});
if (!customer)
throw new common_1.NotFoundException('مشتری یافت نشد');
const agent = await this.prisma.customer.findUnique({
where: { id: agentId },
});
const amounts = customer.orders
.map((o) => o.finalAmount ?? 0)
.filter((n) => n > 0);
const total = amounts.reduce((a, b) => a + b, 0);
const orderCount = customer.orders.length;
const meetings = await this.prisma.meetingInteraction.findMany({
where: { customerId, agentId },
orderBy: { createdAt: 'desc' },
take: 50,
});
return {
customer: {
id: customer.id,
name: customer.businessName || `${customer.firstName} ${customer.lastName}`,
contactName: `${customer.firstName} ${customer.lastName}`,
phone: customer.phone,
status: customer.isActive ? 'active' : 'inactive',
avatarLetter: customer.avatarLetter || customer.firstName.charAt(0),
avatarColor: customer.avatarColor || '#f9a8d4',
totalPurchaseToman: total,
orderCount,
averageOrderToman: orderCount ? Math.round(total / orderCount) : 0,
levelLabel: customer.levelLabel || 'برنزی',
firstPurchaseDate: customer.createdAt.toISOString().slice(0, 10),
agentCode: agent?.agentCode,
agentName: agent ? `${agent.firstName} ${agent.lastName}` : undefined,
},
orders: customer.orders.map((o) => ({
id: o.id,
customerId: customer.id,
title: `سفارش #${o.orderNumber}`,
amountToman: o.finalAmount ?? 0,
statusLabel: o.status,
statusTone: 'info',
date: o.createdAt.toISOString().slice(0, 10),
})),
meetings: meetings.map((m) => ({
id: m.id,
customerId: m.customerId,
type: m.type,
title: m.title,
description: m.description ?? '',
date: m.date,
time: m.time ?? undefined,
})),
};
}
async createMeeting(agentId, dto) {
await this.requireAgent(agentId);
const customer = await this.prisma.customer.findFirst({
where: { id: dto.customerId, assignedAgentId: agentId },
});
if (!customer)
throw new common_1.NotFoundException('مشتری یافت نشد');
const meeting = await this.prisma.meetingInteraction.create({
data: {
agentId,
customerId: dto.customerId,
type: dto.type,
title: dto.title.trim(),
description: dto.description?.trim(),
subject: dto.subject?.trim(),
content: dto.content?.trim(),
date: dto.date,
time: dto.time,
},
});
let reminder = null;
if (dto.createReminder && dto.reminderTitle && dto.reminderDate && dto.reminderTime) {
reminder = await this.prisma.reminder.create({
data: {
ownerId: agentId,
customerId: dto.customerId,
title: dto.reminderTitle.trim(),
description: dto.reminderNote?.trim(),
note: dto.reminderNote?.trim(),
date: dto.reminderDate,
time: dto.reminderTime,
interactionType: dto.type,
},
});
}
return { meeting, reminder };
}
async listReminders(agentId, filter) {
await this.requireAgent(agentId);
const where = { ownerId: agentId };
if (filter === 'past') {
where.completed = true;
}
else if (filter === 'all') {
}
else {
where.completed = false;
}
const reminders = await this.prisma.reminder.findMany({
where,
orderBy: [{ date: 'asc' }, { time: 'asc' }],
include: {
customer: true,
},
});
return reminders.map((r) => ({
id: r.id,
customerId: r.customerId,
title: r.title,
description: r.description ?? '',
time: r.time,
date: r.date,
interactionType: r.interactionType,
completed: r.completed,
note: r.note ?? undefined,
customerName: r.customer.businessName ||
`${r.customer.firstName} ${r.customer.lastName}`,
contactName: `${r.customer.firstName} ${r.customer.lastName}`,
avatarLetter: r.customer.avatarLetter || r.customer.firstName.charAt(0),
avatarColor: r.customer.avatarColor || '#c4b5fd',
}));
}
async getReminder(agentId, reminderId) {
await this.requireAgent(agentId);
const reminder = await this.prisma.reminder.findFirst({
where: { id: reminderId, ownerId: agentId },
include: { customer: true },
});
if (!reminder)
throw new common_1.NotFoundException('یادآور یافت نشد');
const history = await this.prisma.meetingInteraction.findMany({
where: { customerId: reminder.customerId, agentId },
orderBy: { createdAt: 'desc' },
take: 20,
});
return {
reminder: {
id: reminder.id,
customerId: reminder.customerId,
title: reminder.title,
description: reminder.description ?? '',
time: reminder.time,
date: reminder.date,
interactionType: reminder.interactionType,
completed: reminder.completed,
note: reminder.note ?? undefined,
},
customer: {
id: reminder.customer.id,
name: reminder.customer.businessName ||
`${reminder.customer.firstName} ${reminder.customer.lastName}`,
contactName: `${reminder.customer.firstName} ${reminder.customer.lastName}`,
phone: reminder.customer.phone,
avatarLetter: reminder.customer.avatarLetter || reminder.customer.firstName.charAt(0),
avatarColor: reminder.customer.avatarColor || '#f9a8d4',
},
history: history.map((m) => ({
id: m.id,
type: m.type,
title: m.title,
description: m.description ?? '',
date: m.date,
})),
};
}
async createReminder(agentId, dto) {
await this.requireAgent(agentId);
const customer = await this.prisma.customer.findFirst({
where: { id: dto.customerId, assignedAgentId: agentId },
});
if (!customer)
throw new common_1.NotFoundException('مشتری یافت نشد');
return this.prisma.reminder.create({
data: {
ownerId: agentId,
customerId: dto.customerId,
title: dto.title.trim(),
description: dto.description?.trim(),
note: dto.note?.trim(),
date: dto.date,
time: dto.time,
interactionType: dto.interactionType ?? client_1.InteractionType.note,
},
});
}
async completeReminder(agentId, reminderId, dto) {
await this.requireAgent(agentId);
const reminder = await this.prisma.reminder.findFirst({
where: { id: reminderId, ownerId: agentId },
});
if (!reminder)
throw new common_1.NotFoundException('یادآور یافت نشد');
const completed = dto.completed ?? true;
return this.prisma.reminder.update({
where: { id: reminderId },
data: {
completed,
completedAt: completed ? new Date() : null,
},
});
}
async listCategories() {
return {
usage: [
{ id: 'trousers', title: 'پارچه‌های شلواری', subtitle: 'مشاهده محصولات' },
{ id: 'suit', title: 'پارچه‌های کت‌شلواری', subtitle: 'مشاهده محصولات' },
{ id: 'shirt', title: 'پارچه‌های پیراهنی', subtitle: 'مشاهده محصولات' },
],
seasons: [
{
id: 'summer',
title: 'تابستانه',
description: 'سبک، خنک و مناسب فصل گرم',
},
{
id: 'winter',
title: 'زمستانه',
description: 'گرم و مناسب فصل سرد',
},
{
id: 'all_season',
title: 'چهارفصل',
description: 'مناسب استفاده در بیشتر فصل‌های سال',
},
],
};
}
};
exports.AgentService = AgentService;
exports.AgentService = AgentService = __decorate([
(0, common_1.Injectable)(),
__metadata("design:paramtypes", [prisma_service_1.PrismaService])
], AgentService);
//# sourceMappingURL=agent.service.js.map