7/7/405
This commit is contained in:
@@ -3,6 +3,7 @@ import { NotificationTone, OrderStatus } from '@prisma/client';
|
|||||||
/** رویدادهایی که برای مشتری اعلان و پیامک تولید میکنند. */
|
/** رویدادهایی که برای مشتری اعلان و پیامک تولید میکنند. */
|
||||||
export type CustomerEvent =
|
export type CustomerEvent =
|
||||||
| 'order_submitted'
|
| 'order_submitted'
|
||||||
|
| 'order_registered_by_admin'
|
||||||
| 'invoice_priced'
|
| 'invoice_priced'
|
||||||
| 'checks_approved'
|
| 'checks_approved'
|
||||||
| 'checks_need_fix'
|
| 'checks_need_fix'
|
||||||
@@ -87,6 +88,15 @@ export const CUSTOMER_EVENTS: Record<CustomerEvent, CustomerEventTemplate> = {
|
|||||||
tone: NotificationTone.info,
|
tone: NotificationTone.info,
|
||||||
smsSwitch: 'smsOrderRegistered',
|
smsSwitch: 'smsOrderRegistered',
|
||||||
},
|
},
|
||||||
|
order_registered_by_admin: {
|
||||||
|
title: 'پیشسفارش برای شما ثبت شد',
|
||||||
|
body: (c) =>
|
||||||
|
`پیشسفارش ${c.orderNumber} توسط کارشناسان ما ثبت شد و برای قیمتگذاری در صف بررسی است.`,
|
||||||
|
sms: (c) =>
|
||||||
|
`پیشسفارش ${c.orderNumber} در ${c.appName} برای شما ثبت شد. پس از قیمتگذاری مطلع میشوید.`,
|
||||||
|
tone: NotificationTone.info,
|
||||||
|
smsSwitch: 'smsOrderRegistered',
|
||||||
|
},
|
||||||
invoice_priced: {
|
invoice_priced: {
|
||||||
title: 'فاکتور سفارش شما صادر شد',
|
title: 'فاکتور سفارش شما صادر شد',
|
||||||
body: (c) =>
|
body: (c) =>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
ArrayMinSize,
|
ArrayMinSize,
|
||||||
IsArray,
|
IsArray,
|
||||||
IsBoolean,
|
|
||||||
IsDateString,
|
IsDateString,
|
||||||
IsEnum,
|
IsEnum,
|
||||||
IsNumber,
|
IsNumber,
|
||||||
@@ -262,16 +261,6 @@ export class UpdateOrderStatusDto {
|
|||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
note?: string;
|
note?: string;
|
||||||
|
|
||||||
@IsOptional()
|
|
||||||
@IsString()
|
|
||||||
reason?: string;
|
|
||||||
|
|
||||||
/** عبور از ماشین وضعیت؛ فقط با ذکر دلیل و با ثبت در تاریخچه. */
|
|
||||||
@IsOptional()
|
|
||||||
@Type(() => Boolean)
|
|
||||||
@IsBoolean()
|
|
||||||
force?: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class UpdateOrderChecksDto {
|
export class UpdateOrderChecksDto {
|
||||||
|
|||||||
@@ -327,6 +327,11 @@ export class OrdersService {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.notifications.dispatchOrderEvent(
|
||||||
|
order.id,
|
||||||
|
'order_registered_by_admin',
|
||||||
|
);
|
||||||
|
|
||||||
return this.mapOrder(order, true);
|
return this.mapOrder(order, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -511,15 +516,7 @@ export class OrdersService {
|
|||||||
return this.mapOrder(order, true);
|
return this.mapOrder(order, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dto.force) {
|
assertTransition(order.status, dto.status);
|
||||||
if (!dto.reason?.trim()) {
|
|
||||||
throw new BadRequestException(
|
|
||||||
'برای تغییر دستی وضعیت، ذکر دلیل الزامی است',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
assertTransition(order.status, dto.status);
|
|
||||||
}
|
|
||||||
|
|
||||||
// فاکتور بدون مبلغ نباید برای مشتری ارسال شود
|
// فاکتور بدون مبلغ نباید برای مشتری ارسال شود
|
||||||
if (
|
if (
|
||||||
@@ -550,10 +547,8 @@ export class OrdersService {
|
|||||||
fromStatus: order.status,
|
fromStatus: order.status,
|
||||||
toStatus: dto.status,
|
toStatus: dto.status,
|
||||||
changedBy: `admin:${adminId}`,
|
changedBy: `admin:${adminId}`,
|
||||||
note: dto.force
|
note: dto.note || null,
|
||||||
? `تغییر دستی وضعیت${dto.note ? ` — ${dto.note}` : ''}`
|
reason: null,
|
||||||
: dto.note || null,
|
|
||||||
reason: dto.reason || null,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -568,7 +563,7 @@ export class OrdersService {
|
|||||||
const event = eventForStatus(dto.status);
|
const event = eventForStatus(dto.status);
|
||||||
if (event) {
|
if (event) {
|
||||||
this.notifications.dispatchOrderEvent(id, event, {
|
this.notifications.dispatchOrderEvent(id, event, {
|
||||||
note: dto.reason ?? dto.note ?? null,
|
note: dto.note ?? null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ const PRODUCT_INCLUDE = {
|
|||||||
isNew: true,
|
isNew: true,
|
||||||
colorsJson: true,
|
colorsJson: true,
|
||||||
imageUrlsJson: true,
|
imageUrlsJson: true,
|
||||||
|
widthCm: true,
|
||||||
|
composition: true,
|
||||||
catalog: { select: { name: true, code: true } },
|
catalog: { select: { name: true, code: true } },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -143,11 +145,15 @@ export class SuggestionsService {
|
|||||||
isNew: boolean;
|
isNew: boolean;
|
||||||
colorsJson: unknown;
|
colorsJson: unknown;
|
||||||
imageUrlsJson: unknown;
|
imageUrlsJson: unknown;
|
||||||
|
widthCm: number | null;
|
||||||
|
composition: string | null;
|
||||||
catalog: { name: string; code: string } | null;
|
catalog: { name: string; code: string } | null;
|
||||||
};
|
};
|
||||||
}) {
|
}) {
|
||||||
const colorEntries = parseColorEntries(r.product.colorsJson, r.product.color);
|
const colorEntries = parseColorEntries(r.product.colorsJson, r.product.color);
|
||||||
const images = mergeProductImages(colorEntries, r.product.imageUrlsJson);
|
const images = mergeProductImages(colorEntries, r.product.imageUrlsJson);
|
||||||
|
const colors = colorEntries.map((entry) => entry.name);
|
||||||
|
const colorImages = colorEntries.map((entry) => entry.imageUrl ?? null);
|
||||||
const catalogName = r.product.catalog?.name;
|
const catalogName = r.product.catalog?.name;
|
||||||
const subtitle =
|
const subtitle =
|
||||||
r.product.subtitle?.trim() ||
|
r.product.subtitle?.trim() ||
|
||||||
@@ -167,6 +173,10 @@ export class SuggestionsService {
|
|||||||
color: r.product.color,
|
color: r.product.color,
|
||||||
subtitle,
|
subtitle,
|
||||||
imageUrl: images[0] ?? undefined,
|
imageUrl: images[0] ?? undefined,
|
||||||
|
colors,
|
||||||
|
colorImages,
|
||||||
|
widthCm: r.product.widthCm ?? undefined,
|
||||||
|
composition: r.product.composition?.trim() || undefined,
|
||||||
isNew: r.product.isNew,
|
isNew: r.product.isNew,
|
||||||
note: r.note ?? undefined,
|
note: r.note ?? undefined,
|
||||||
isActive: r.isActive,
|
isActive: r.isActive,
|
||||||
|
|||||||
Reference in New Issue
Block a user