import { prisma } from "@/lib/prisma"; import type { BusinessCustomerDto, BusinessCustomerStatus, } from "@/modules/customer/types"; import { ValidationError } from "@/modules/quote/types"; function serializeBusinessCustomer(row: { customerId: string; businessCustomerId: string; name: string; externalCode: string | null; status: string; remark: string | null; createdAt: Date; updatedAt: Date; }): BusinessCustomerDto { return { customer_id: row.customerId, business_customer_id: row.businessCustomerId, name: row.name, external_code: row.externalCode, status: row.status as BusinessCustomerStatus, remark: row.remark, created_at: row.createdAt.toISOString(), updated_at: row.updatedAt.toISOString(), }; } export async function listBusinessCustomers(customerId: string): Promise { const rows = await prisma.businessCustomer.findMany({ where: { customerId, isDeleted: false }, orderBy: { createdAt: "desc" }, include: { _count: { select: { users: { where: { isDeleted: false, status: "active" }, }, }, }, }, }); return rows.map((row) => ({ ...serializeBusinessCustomer(row), user_count: row._count.users, })); } export async function createBusinessCustomer(input: { customerId: string; businessCustomerId: string; name: string; externalCode?: string | null; remark?: string | null; }): Promise { const customerId = input.customerId.trim(); const businessCustomerId = input.businessCustomerId.trim(); const name = input.name.trim(); if (!customerId) { throw new Error("租户标识不能为空"); } if (!businessCustomerId) { throw new Error("客户标识不能为空"); } if (!name) { throw new Error("客户名称不能为空"); } const created = await prisma.businessCustomer.create({ data: { customerId, businessCustomerId, name, externalCode: input.externalCode?.trim() || null, remark: input.remark?.trim() || null, status: "active", }, }); return serializeBusinessCustomer(created); } export async function updateBusinessCustomer( customerId: string, businessCustomerId: string, input: { name?: string; externalCode?: string | null; status?: BusinessCustomerStatus; remark?: string | null; }, ): Promise { const existing = await prisma.businessCustomer.findFirst({ where: { customerId, businessCustomerId, isDeleted: false }, }); if (!existing) { throw new Error("客户不存在"); } const data: { name?: string; externalCode?: string | null; status?: BusinessCustomerStatus; remark?: string | null; } = {}; if (input.name !== undefined) { const name = input.name.trim(); if (!name) { throw new Error("客户名称不能为空"); } data.name = name; } if (input.externalCode !== undefined) { data.externalCode = input.externalCode?.trim() || null; } if (input.status !== undefined) { data.status = input.status; } if (input.remark !== undefined) { data.remark = input.remark?.trim() || null; } const updated = await prisma.businessCustomer.update({ where: { customerId_businessCustomerId: { customerId, businessCustomerId, }, }, data, }); return serializeBusinessCustomer(updated); } export async function getBusinessCustomer( customerId: string, businessCustomerId: string, ): Promise { const row = await prisma.businessCustomer.findFirst({ where: { customerId, businessCustomerId, isDeleted: false }, }); return row ? serializeBusinessCustomer(row) : null; } export async function assertBusinessCustomerBelongsToTenant( customerId: string, businessCustomerId?: string | null, ): Promise { if (!businessCustomerId) { return; } const exists = await prisma.businessCustomer.count({ where: { customerId, businessCustomerId, isDeleted: false, status: "active", }, }); if (!exists) { throw new ValidationError("客户不存在或已停用"); } }