Files
2026-08-15 10:38:10 +03:30

722 lines
32 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.OrdersService = void 0;
const common_1 = require("@nestjs/common");
const client_1 = require("@prisma/client");
const prisma_service_1 = require("../prisma/prisma.service");
const order_number_1 = require("../common/utils/order-number");
const check_rass_1 = require("../common/utils/check-rass");
const cash_expiry_1 = require("../common/utils/cash-expiry");
const order_status_1 = require("../common/utils/order-status");
const order_transitions_1 = require("../common/utils/order-transitions");
const meterage_1 = require("../common/utils/meterage");
const notifications_service_1 = require("../notifications/notifications.service");
const notification_events_1 = require("../notifications/notification-events");
const name_1 = require("../common/utils/name");
const phone_1 = require("../common/utils/phone");
const orderInclude = {
items: true,
checks: { orderBy: { row: 'asc' } },
cashReceipt: true,
statusHistory: { orderBy: { changedAt: 'asc' } },
shipment: true,
user: true,
company: true,
};
function roundMoney(value) {
return Math.round(value * 100) / 100;
}
const CHECK_EDITABLE_STATUSES = [
client_1.OrderStatus.check_in_progress,
client_1.OrderStatus.awaiting_check_review,
client_1.OrderStatus.check_needs_fix,
client_1.OrderStatus.check_rejected,
];
const PRICE_HIDDEN_STATUSES = [
client_1.OrderStatus.awaiting_review,
client_1.OrderStatus.pricing,
];
let OrdersService = class OrdersService {
prisma;
notifications;
constructor(prisma, notifications) {
this.prisma = prisma;
this.notifications = notifications;
}
async findMyOrders(userId) {
const orders = await this.prisma.order.findMany({
where: { userId },
orderBy: { createdAt: 'desc' },
include: orderInclude,
});
return orders.map((o) => this.mapOrder(o));
}
async findMyOrder(userId, id) {
const order = await this.getOrder(id);
if (order.userId !== userId) {
throw new common_1.ForbiddenException('دسترسی به این سفارش مجاز نیست');
}
return this.mapOrder(order);
}
async findAdminOrders(filters) {
const statuses = (0, order_status_1.resolveAdminStatusFilter)(filters.status);
const q = filters.q?.trim();
const orders = await this.prisma.order.findMany({
where: {
...(statuses ? { status: { in: statuses } } : {}),
...(q
? {
OR: [
{ orderNumber: { contains: q, mode: 'insensitive' } },
{ companyName: { contains: q, mode: 'insensitive' } },
{
user: {
OR: [
{ firstName: { contains: q, mode: 'insensitive' } },
{ lastName: { contains: q, mode: 'insensitive' } },
{ phone: { contains: (0, phone_1.toEnglishDigits)(q) } },
],
},
},
],
}
: {}),
},
orderBy: { createdAt: 'desc' },
include: orderInclude,
});
return orders.map((o) => this.mapOrder(o, true));
}
async findAdminOrder(id) {
const order = await this.getOrder(id);
return this.mapOrder(order, true);
}
async submitOrder(userId, dto) {
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 common_1.BadRequestException('محصول تکراری در سفارش مجاز نیست');
}
const products = await this.prisma.product.findMany({
where: { id: { in: uniqueProductIds } },
include: { catalog: true, company: true },
});
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 common_1.BadRequestException('یک یا چند محصول نامعتبر است یا دیگر در سیستم وجود ندارد. سبد را خالی کنید و دوباره اضافه کنید.');
}
if (!product.isActive) {
throw new common_1.BadRequestException(`محصول «${product.name}» غیرفعال است و قابل سفارش نیست`);
}
if (!product.company?.isActive) {
throw new common_1.BadRequestException(`شرکت محصول «${product.name}» غیرفعال است`);
}
}
const meterageByCompany = new Map();
for (const item of dto.items) {
const product = productMap.get(item.productId);
const current = meterageByCompany.get(product.companyId);
if (current) {
current.meterage += item.meterage;
}
else {
meterageByCompany.set(product.companyId, {
name: product.company.name,
meterage: item.meterage,
max: product.company.maxMeteragePerInvoice,
});
}
}
for (const row of meterageByCompany.values()) {
const maxMeterageResolved = (0, meterage_1.resolveMaxMeterage)(row.max, settings?.maxMeteragePerInvoice);
if (row.meterage > maxMeterageResolved) {
throw new common_1.BadRequestException(`حداکثر متراژ مجاز فاکتور برای «${row.name}» برابر ${maxMeterageResolved} متر است`);
}
}
let totalMeterage = 0;
const itemsData = dto.items.map((item) => {
const product = productMap.get(item.productId);
if (item.meterage < product.minMeterage) {
throw new common_1.BadRequestException(`حداقل متراژ برای ${product.name} برابر ${product.minMeterage} است`);
}
const rem = Math.round((item.meterage / product.orderMultiplier) * 1000) / 1000;
if (Math.abs(rem - Math.round(rem)) > 1e-6) {
throw new common_1.BadRequestException(`متراژ ${product.name} باید مضرب ${product.orderMultiplier} باشد`);
}
totalMeterage += item.meterage;
return {
productId: product.id,
catalogCode: product.catalog.code,
productName: product.name,
productCode: product.code,
color: product.color,
requestedMeterage: item.meterage,
notes: item.notes?.trim() || null,
companyId: product.companyId,
companyName: product.company.name,
};
});
const companyNames = [
...new Set(itemsData.map((item) => item.companyName).filter(Boolean)),
];
const preferredCompanyId = itemsData.some((item) => item.companyId === dto.companyId)
? dto.companyId
: itemsData[0].companyId;
const primaryCompany = products.find((p) => p.companyId === preferredCompanyId)
?.company;
if (!primaryCompany) {
throw new common_1.NotFoundException('شرکت محصولات یافت نشد یا غیرفعال است');
}
const order = await this.createWithUniqueOrderNumber((orderNumber) => this.prisma.$transaction(async (tx) => {
const created = await tx.order.create({
data: {
orderNumber,
userId,
companyId: primaryCompany.id,
companyName: companyNames.join('، '),
settlementType: null,
checkMode: null,
status: client_1.OrderStatus.awaiting_review,
totalMeterage,
notes: dto.notes?.trim() || null,
items: { create: itemsData },
statusHistory: {
create: [
{
fromStatus: null,
toStatus: client_1.OrderStatus.awaiting_review,
changedBy: 'customer',
note: 'سفارش ثبت شد و برای بررسی مدیریت ارسال شد',
},
],
},
},
include: orderInclude,
});
const cart = await tx.cart.findFirst({ where: { userId } });
if (cart) {
await tx.cartItem.deleteMany({
where: {
cartId: cart.id,
productId: { in: uniqueProductIds },
},
});
const remaining = await tx.cartItem.findFirst({
where: { cartId: cart.id },
});
await tx.cart.update({
where: { id: cart.id },
data: { companyId: remaining?.companyId ?? null },
});
}
return created;
}));
this.notifications.dispatchOrderEvent(order.id, 'order_submitted');
this.notifications.dispatchAdmin({
title: 'سفارش جدید ثبت شد',
body: `سفارش ${order.orderNumber} با ${order.items.length} قلم و ${order.totalMeterage} متر در انتظار قیمت‌گذاری است.`,
link: `/orders/${order.id}`,
});
return this.mapOrder(order);
}
async chooseSettlement(userId, id, dto) {
const order = await this.getOrder(id);
if (order.userId !== userId) {
throw new common_1.ForbiddenException('دسترسی به این سفارش مجاز نیست');
}
if (order.status !== client_1.OrderStatus.awaiting_settlement) {
throw new common_1.BadRequestException('انتخاب روش تسویه فقط پس از صدور فاکتور توسط مدیریت امکان‌پذیر است');
}
const isCash = dto.settlementType === client_1.SettlementType.cash;
const nextStatus = isCash
? client_1.OrderStatus.awaiting_cash_payment
: client_1.OrderStatus.check_in_progress;
(0, order_transitions_1.assertTransition)(order.status, nextStatus);
const cashCompanies = isCash
? await this.companiesForOrder(order)
: [];
await this.prisma.$transaction(async (tx) => {
await tx.order.update({
where: { id },
data: {
settlementType: dto.settlementType,
checkMode: isCash
? null
: (dto.checkMode ?? client_1.CheckRegistrationMode.full),
cashInvoiceExpiresAt: isCash
? (0, cash_expiry_1.earliestCashInvoiceExpiry)(cashCompanies)
: null,
cashReminderSentAt: null,
status: nextStatus,
},
});
await tx.orderStatusHistory.create({
data: {
orderId: id,
fromStatus: order.status,
toStatus: nextStatus,
changedBy: 'customer',
note: isCash
? 'مشتری تسویه نقدی را انتخاب کرد'
: 'مشتری تسویه چکی را انتخاب کرد',
},
});
});
return this.findMyOrder(userId, id);
}
async adminCreate(adminId, dto) {
const company = await this.prisma.company.findUnique({
where: { id: dto.companyId },
});
if (!company)
throw new common_1.NotFoundException('شرکت یافت نشد');
let userId = dto.customerId || dto.userId;
if (userId) {
const existing = await this.prisma.customer.findUnique({
where: { id: userId },
});
if (!existing) {
throw new common_1.BadRequestException('مشتری انتخاب‌شده یافت نشد');
}
}
else if (dto.customerPhone) {
const phone = (0, phone_1.normalizePhone)((0, phone_1.toEnglishDigits)(dto.customerPhone));
if (!(0, phone_1.isValidPhone)(phone)) {
throw new common_1.BadRequestException('شماره موبایل نامعتبر است');
}
let customer = await this.prisma.customer.findUnique({
where: { phone },
});
if (!customer) {
const names = (0, name_1.splitFullName)(dto.customerName || 'مشتری جدید');
customer = await this.prisma.customer.create({
data: {
phone,
firstName: names.firstName,
lastName: names.lastName || 'جدید',
},
});
}
userId = customer.id;
}
if (!userId) {
throw new common_1.BadRequestException('انتخاب مشتری الزامی است');
}
const totalMeterage = dto.meterage ?? 0;
const ownerId = userId;
const order = await this.createWithUniqueOrderNumber((orderNumber) => this.prisma.order.create({
data: {
orderNumber,
userId: ownerId,
companyId: company.id,
companyName: company.name,
settlementType: null,
status: client_1.OrderStatus.awaiting_review,
totalMeterage,
notes: dto.notes?.trim() || null,
statusHistory: {
create: {
fromStatus: null,
toStatus: client_1.OrderStatus.awaiting_review,
changedBy: `admin:${adminId}`,
note: 'سفارش توسط ادمین ثبت شد',
},
},
},
include: orderInclude,
}));
return this.mapOrder(order, true);
}
async updatePricing(id, adminId, dto) {
const order = await this.getOrder(id);
const unknown = dto.items.find((item) => !order.items.some((i) => i.id === item.id));
if (unknown) {
throw new common_1.BadRequestException(`آیتم ${unknown.id} یافت نشد`);
}
await this.prisma.$transaction(async (tx) => {
let totalAmount = 0;
let totalMeterage = 0;
for (const existing of order.items) {
const item = dto.items.find((i) => i.id === existing.id);
const unitPrice = item?.unitPrice !== undefined
? item.unitPrice
: item?.supplyPrice !== undefined
? item.supplyPrice
: (existing.unitPrice ?? 0);
const unitDiscount = item?.unitDiscount ?? existing.unitDiscount ?? 0;
if (unitDiscount > unitPrice) {
throw new common_1.BadRequestException('تخفیف واحد نمی‌تواند از قیمت واحد بیشتر باشد');
}
const confirmed = item?.confirmedMeterage ??
existing.confirmedMeterage ??
existing.requestedMeterage;
const lineTotal = roundMoney(Math.max(0, (unitPrice - unitDiscount) * confirmed));
totalAmount += lineTotal;
totalMeterage += confirmed;
if (!item)
continue;
await tx.orderItem.update({
where: { id: existing.id },
data: {
confirmedMeterage: confirmed,
unitPrice,
unitDiscount,
lineTotal,
},
});
}
totalAmount = roundMoney(totalAmount);
const shippingCost = dto.shippingCost ?? order.shippingCost ?? 0;
const totalDiscount = dto.totalDiscount ?? order.totalDiscount ?? 0;
const finalAmount = roundMoney(Math.max(0, totalAmount + shippingCost - totalDiscount));
const nextStatus = order.status === client_1.OrderStatus.awaiting_review ||
order.status === client_1.OrderStatus.pricing
? client_1.OrderStatus.pricing
: order.status;
await tx.order.update({
where: { id },
data: {
totalAmount,
totalMeterage,
shippingCost,
totalDiscount,
finalAmount,
status: nextStatus,
},
});
if (nextStatus !== order.status) {
await tx.orderStatusHistory.create({
data: {
orderId: id,
fromStatus: order.status,
toStatus: nextStatus,
changedBy: `admin:${adminId}`,
note: dto.note || 'قیمت‌گذاری انجام شد',
},
});
}
});
return this.findAdminOrder(id);
}
async updateStatus(id, adminId, dto) {
const order = await this.getOrder(id);
if (order.status === dto.status) {
return this.mapOrder(order, true);
}
if (dto.force) {
if (!dto.reason?.trim()) {
throw new common_1.BadRequestException('برای تغییر دستی وضعیت، ذکر دلیل الزامی است');
}
}
else {
(0, order_transitions_1.assertTransition)(order.status, dto.status);
}
if (dto.status === client_1.OrderStatus.awaiting_settlement &&
(order.finalAmount ?? 0) <= 0) {
throw new common_1.BadRequestException('ابتدا سفارش را قیمت‌گذاری کنید تا فاکتور قابل ارسال باشد');
}
const needsCashExpiry = (dto.status === client_1.OrderStatus.cash_invoice_issued ||
dto.status === client_1.OrderStatus.awaiting_cash_payment) &&
!order.cashInvoiceExpiresAt;
const cashExpiry = needsCashExpiry
? (0, cash_expiry_1.earliestCashInvoiceExpiry)(await this.companiesForOrder(order))
: null;
await this.prisma.$transaction(async (tx) => {
await tx.order.update({
where: { id },
data: { status: dto.status },
});
await tx.orderStatusHistory.create({
data: {
orderId: id,
fromStatus: order.status,
toStatus: dto.status,
changedBy: `admin:${adminId}`,
note: dto.force
? `تغییر دستی وضعیت${dto.note ? ` — ${dto.note}` : ''}`
: dto.note || null,
reason: dto.reason || null,
},
});
if (cashExpiry) {
await tx.order.update({
where: { id },
data: { cashInvoiceExpiresAt: cashExpiry },
});
}
});
const event = (0, notification_events_1.eventForStatus)(dto.status);
if (event) {
this.notifications.dispatchOrderEvent(id, event, {
note: dto.reason ?? dto.note ?? null,
});
}
return this.findAdminOrder(id);
}
async updateChecks(userId, id, dto) {
const order = await this.getOrder(id);
if (order.userId !== userId) {
throw new common_1.ForbiddenException('دسترسی به این سفارش مجاز نیست');
}
if (order.settlementType !== client_1.SettlementType.check) {
throw new common_1.BadRequestException('این سفارش تسویه چکی نیست');
}
if (!CHECK_EDITABLE_STATUSES.includes(order.status)) {
throw new common_1.BadRequestException('در وضعیت فعلی سفارش امکان ویرایش چک‌ها وجود ندارد');
}
if (!dto.checks.length) {
throw new common_1.BadRequestException('حداقل یک چک لازم است');
}
const checkMode = dto.checkMode ?? order.checkMode ?? client_1.CheckRegistrationMode.full;
const rass = (0, check_rass_1.calculateCheckRass)(dto.checks.map((c) => ({ amount: c.amount, dueDate: c.dueDate })), order.createdAt);
const goesToReview = order.status === client_1.OrderStatus.check_in_progress ||
order.status === client_1.OrderStatus.check_needs_fix ||
order.status === client_1.OrderStatus.check_rejected;
const nextStatus = goesToReview
? client_1.OrderStatus.awaiting_check_review
: order.status;
const isFix = order.status !== client_1.OrderStatus.check_in_progress;
await this.prisma.$transaction(async (tx) => {
await tx.check.deleteMany({ where: { orderId: id } });
await tx.check.createMany({
data: dto.checks.map((c, index) => ({
orderId: id,
...this.mapCheckCreate(c, index + 1, checkMode),
})),
});
await tx.order.update({
where: { id },
data: {
checkMode,
checkRassDays: rass.rassDays,
checkRassDate: rass.rassDate ? new Date(rass.rassDate) : null,
status: nextStatus,
},
});
if (nextStatus !== order.status) {
await tx.orderStatusHistory.create({
data: {
orderId: id,
fromStatus: order.status,
toStatus: nextStatus,
changedBy: 'customer',
note: isFix
? 'چک‌ها اصلاح و مجدداً ارسال شد'
: 'چک‌ها برای بررسی ارسال شد',
},
});
}
});
if (nextStatus !== order.status) {
this.notifications.dispatchAdmin({
title: isFix ? 'چک‌های اصلاح‌شده رسید' : 'چک‌های سفارش ثبت شد',
body: `مشتری ${dto.checks.length} چک برای سفارش ${order.orderNumber} ثبت کرد و منتظر بررسی است.`,
link: `/orders/${id}/checks`,
});
}
return this.findMyOrder(userId, id);
}
mapCheckCreate(c, row, defaultMode) {
return {
row,
amount: c.amount,
dueDate: new Date(c.dueDate),
sayadId: c.sayadId?.trim() || null,
checkNumber: c.checkNumber?.trim() || null,
ownerNationalId: c.ownerNationalId?.trim() || null,
ownerFirstName: c.ownerFirstName?.trim() || null,
ownerLastName: c.ownerLastName?.trim() || null,
bankName: c.bankName?.trim() || null,
branchName: c.branchName?.trim() || null,
frontImage: c.frontImage || null,
backImage: c.backImage || null,
notes: c.notes?.trim() || null,
mode: c.mode ?? defaultMode,
};
}
async nextOrderNumber() {
for (let i = 0; i < 5; i++) {
const orderNumber = (0, order_number_1.generateOrderNumber)();
const exists = await this.prisma.order.findUnique({
where: { orderNumber },
});
if (!exists)
return orderNumber;
}
return `${(0, order_number_1.generateOrderNumber)()}-${Date.now().toString().slice(-3)}`;
}
async createWithUniqueOrderNumber(create) {
for (let attempt = 0;; attempt++) {
const orderNumber = await this.nextOrderNumber();
try {
return await create(orderNumber);
}
catch (e) {
const isDuplicate = e instanceof client_1.Prisma.PrismaClientKnownRequestError &&
e.code === 'P2002';
if (!isDuplicate || attempt >= 4)
throw e;
}
}
}
async companiesForOrder(order) {
const companyIds = [
...new Set([
order.companyId,
...order.items.map((item) => item.companyId).filter(Boolean),
].filter(Boolean)),
];
if (!companyIds.length)
return order.company ? [order.company] : [];
const companies = await this.prisma.company.findMany({
where: { id: { in: companyIds } },
});
return companies.length ? companies : order.company ? [order.company] : [];
}
async getOrder(id) {
const order = await this.prisma.order.findUnique({
where: { id },
include: orderInclude,
});
if (!order)
throw new common_1.NotFoundException('سفارش یافت نشد');
return order;
}
mapOrder(order, adminView = false) {
const customerName = (0, name_1.joinFullName)(order.user.firstName, order.user.lastName);
const hidePrices = !adminView && PRICE_HIDDEN_STATUSES.includes(order.status);
const base = {
id: order.id,
orderNumber: order.orderNumber,
userId: order.userId,
companyId: order.companyId,
companyName: order.companyName,
settlementType: order.settlementType,
settlementMethod: order.settlementType,
checkMode: order.checkMode ?? undefined,
status: order.status,
adminStatus: (0, order_status_1.toAdminStatus)(order.status),
allowedTransitions: adminView ? (0, order_transitions_1.allowedTransitions)(order.status) : [],
totalMeterage: order.totalMeterage,
meterage: order.totalMeterage,
totalAmount: hidePrices ? null : order.totalAmount,
shippingCost: hidePrices ? null : order.shippingCost,
totalDiscount: hidePrices ? null : order.totalDiscount,
finalAmount: hidePrices ? null : order.finalAmount,
pricesVisible: !hidePrices,
notes: order.notes ?? undefined,
checkRassDays: order.checkRassDays ?? undefined,
checkRassDate: order.checkRassDate?.toISOString(),
cashInvoiceExpiresAt: order.cashInvoiceExpiresAt?.toISOString(),
createdAt: order.createdAt.toISOString(),
updatedAt: order.updatedAt.toISOString(),
customerName,
customerPhone: order.user.phone,
customerNationalId: order.user.nationalId ?? undefined,
customerType: order.user.customerType,
items: order.items.map((item) => ({
id: item.id,
productId: item.productId ?? undefined,
catalogCode: item.catalogCode,
productName: item.productName,
productCode: item.productCode ?? undefined,
color: item.color,
requestedMeterage: item.requestedMeterage,
confirmedMeterage: item.confirmedMeterage,
unitPrice: hidePrices ? null : item.unitPrice,
supplyPrice: hidePrices ? null : item.unitPrice,
unitDiscount: hidePrices ? null : (item.unitDiscount ?? 0),
discount: hidePrices ? null : (item.unitDiscount ?? 0),
lineTotal: hidePrices ? null : item.lineTotal,
totalAmount: hidePrices ? null : item.lineTotal,
notes: item.notes ?? undefined,
companyId: item.companyId,
companyName: item.companyName,
})),
checks: order.checks.map((c) => ({
id: c.id,
orderId: c.orderId,
row: c.row,
amount: c.amount,
dueDate: c.dueDate.toISOString(),
sayadId: c.sayadId ?? undefined,
checkNumber: c.checkNumber ?? undefined,
ownerNationalId: c.ownerNationalId ?? undefined,
ownerFirstName: c.ownerFirstName ?? undefined,
ownerLastName: c.ownerLastName ?? undefined,
bankName: c.bankName ?? '',
branchName: c.branchName ?? undefined,
frontImage: c.frontImage ?? undefined,
backImage: c.backImage ?? undefined,
notes: c.notes ?? undefined,
mode: c.mode,
status: c.status,
createdAt: c.createdAt.toISOString(),
updatedAt: c.updatedAt.toISOString(),
})),
cashReceipt: order.cashReceipt
? {
id: order.cashReceipt.id,
amount: order.cashReceipt.amount,
paidAmount: order.cashReceipt.paidAmount,
transferDate: order.cashReceipt.transferDate?.toISOString() ?? null,
transferTime: order.cashReceipt.transferTime ?? undefined,
trackingNumber: order.cashReceipt.trackingNumber ?? undefined,
trackingCode: order.cashReceipt.trackingNumber ?? undefined,
destinationAccountId: order.cashReceipt.destinationAccountId ?? undefined,
receiptImage: order.cashReceipt.receiptImage ?? undefined,
notes: order.cashReceipt.notes ?? undefined,
expiresAt: order.cashReceipt.expiresAt?.toISOString() ??
order.cashInvoiceExpiresAt?.toISOString(),
status: order.cashReceipt.status,
submittedAt: order.cashReceipt.submittedAt?.toISOString(),
createdAt: order.cashReceipt.createdAt.toISOString(),
}
: undefined,
shipment: order.shipment
? {
id: order.shipment.id,
orderId: order.shipment.orderId,
carrier: order.shipment.carrier,
trackingNumber: order.shipment.trackingNumber ?? '',
meterage: order.shipment.meterage,
status: order.shipment.status,
shippedAt: order.shipment.shippedAt?.toISOString() ?? null,
deliveredAt: order.shipment.deliveredAt?.toISOString() ?? null,
}
: undefined,
statusHistory: order.statusHistory.map((h) => ({
id: h.id,
fromStatus: h.fromStatus,
toStatus: h.toStatus,
changedBy: h.changedBy,
note: h.note ?? undefined,
reason: h.reason ?? undefined,
changedAt: h.changedAt.toISOString(),
})),
};
return base;
}
};
exports.OrdersService = OrdersService;
exports.OrdersService = OrdersService = __decorate([
(0, common_1.Injectable)(),
__metadata("design:paramtypes", [prisma_service_1.PrismaService,
notifications_service_1.NotificationsService])
], OrdersService);
//# sourceMappingURL=orders.service.js.map