diff --git a/src/carts/carts.service.ts b/src/carts/carts.service.ts index 281bcf6..5791441 100644 --- a/src/carts/carts.service.ts +++ b/src/carts/carts.service.ts @@ -113,9 +113,16 @@ export class CartsService { if (!item) throw new NotFoundException('آیتم سبد یافت نشد'); await this.prisma.cartItem.delete({ where: { id: itemId } }); + const remaining = await this.prisma.cartItem.findMany({ + where: { cartId: cart.id }, + take: 1, + }); await this.prisma.cart.update({ where: { id: cart.id }, - data: { updatedAt: new Date() }, + data: { + companyId: remaining[0]?.companyId ?? null, + updatedAt: new Date(), + }, }); return this.getCart(userId); diff --git a/src/orders/orders.service.ts b/src/orders/orders.service.ts index cef3758..5662ab5 100644 --- a/src/orders/orders.service.ts +++ b/src/orders/orders.service.ts @@ -135,31 +135,59 @@ export class OrdersService { } async submitOrder(userId: string, dto: SubmitOrderDto) { - const [company, settings] = await Promise.all([ - this.prisma.company.findUnique({ where: { id: dto.companyId } }), - this.prisma.systemSettings.findUnique({ - where: { id: 'default' }, - select: { maxMeteragePerInvoice: true }, - }), - ]); - if (!company || !company.isActive) { - throw new NotFoundException('شرکت یافت نشد یا غیرفعال است'); - } - const maxMeterage = resolveMaxMeterage( - company.maxMeteragePerInvoice, - settings?.maxMeteragePerInvoice, - ); + const settings = await this.prisma.systemSettings.findUnique({ + where: { id: 'default' }, + select: { maxMeteragePerInvoice: true }, + }); const productIds = dto.items.map((i) => i.productId); + const uniqueProductIds = [...new Set(productIds)]; + if (uniqueProductIds.length !== productIds.length) { + throw new BadRequestException('محصول تکراری در سفارش مجاز نیست'); + } + const products = await this.prisma.product.findMany({ - where: { id: { in: productIds }, companyId: company.id, isActive: true }, + where: { id: { in: uniqueProductIds } }, include: { catalog: true }, }); - if (products.length !== productIds.length) { - throw new BadRequestException('یک یا چند محصول نامعتبر است'); - } const productMap = new Map(products.map((p) => [p.id, p])); + for (const item of dto.items) { + const product = productMap.get(item.productId); + if (!product) { + throw new BadRequestException( + 'یک یا چند محصول نامعتبر است یا دیگر در سیستم وجود ندارد. سبد را خالی کنید و دوباره اضافه کنید.', + ); + } + if (!product.isActive) { + throw new BadRequestException( + `محصول «${product.name}» غیرفعال است و قابل سفارش نیست`, + ); + } + } + + const productCompanyIds = [ + ...new Set(products.map((p) => p.companyId)), + ]; + if (productCompanyIds.length !== 1) { + throw new BadRequestException( + 'اقلام سفارش باید همه از یک شرکت باشند', + ); + } + + // شرکت را از خود محصولات resolve کن تا companyId کهنه/ناسازگار سبد خطا ندهد + const orderCompany = await this.prisma.company.findUnique({ + where: { id: productCompanyIds[0]! }, + }); + if (!orderCompany || !orderCompany.isActive) { + throw new NotFoundException('شرکت محصولات یافت نشد یا غیرفعال است'); + } + + const maxMeterageResolved = resolveMaxMeterage( + orderCompany.maxMeteragePerInvoice, + settings?.maxMeteragePerInvoice, + ); + let totalMeterage = 0; const itemsData = dto.items.map((item) => { const product = productMap.get(item.productId)!; @@ -187,9 +215,9 @@ export class OrdersService { }; }); - if (totalMeterage > maxMeterage) { + if (totalMeterage > maxMeterageResolved) { throw new BadRequestException( - `حداکثر متراژ مجاز هر فاکتور ${maxMeterage} متر است`, + `حداکثر متراژ مجاز هر فاکتور ${maxMeterageResolved} متر است`, ); } @@ -200,8 +228,8 @@ export class OrdersService { data: { orderNumber, userId, - companyId: company.id, - companyName: company.name, + companyId: orderCompany.id, + companyName: orderCompany.name, settlementType: null, checkMode: null, status: OrderStatus.awaiting_review,