feat: port QA/money fixes from tehran_taj (atomic document confirm, validated inputs, expert customer edit/toggle/weights, made-to-order, grid sort/customer column)

Order-revision workflow kept as is: the direct admin line-edit routes were not ported.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
saeed
2026-10-29 18:43:22 +03:30
co-authored by Claude Sonnet 5.5
parent 756ecef6db
commit 3eaecde876
65 changed files with 3810 additions and 216 deletions
@@ -37,6 +37,7 @@ export class AdminPreOrdersService {
'sizeSpec',
'stoneColor',
'minaColor',
'quantity',
'estimatedWeightGrams',
'estimatedPriceRial',
'customer.fullName',
@@ -47,7 +48,10 @@ export class AdminPreOrdersService {
async list(query: TableQueryDto) {
this.table.assertNotExport(query);
const { where, orderBy, skip, take, page, limit } = this.table.build(query, {
// The «تعداد» column is keyed `sum` (legacy name); the stored field is `quantity`.
const sorted = query.order && /^[+-]?sum$/.test(query.order) ? { ...query, order: query.order.replace('sum', 'quantity') } : query;
const { where, orderBy, skip, take, page, limit } = this.table.build(sorted, {
searchable: ['customer.fullName', 'customer.mobile'],
allowed: AdminPreOrdersService.ALLOWED,
defaultOrderBy: { createdAt: 'desc' },
@@ -79,8 +83,8 @@ export class AdminPreOrdersService {
size: p.sizeSpec,
color_mina: p.minaColor,
color_stone: p.stoneColor,
// legacy 'sum' (quantity); a PreOrder models a single design request
sum: 1,
// legacy 'sum' — the pieces asked for
sum: p.quantity,
description: p.description,
designImageUrl: p.designImageUrl,
estimatedWeightGrams: p.estimatedWeightGrams,
@@ -123,6 +127,11 @@ export class AdminPreOrdersService {
if (data.color_mina !== undefined) patch.minaColor = data.color_mina as string;
if (data.color_stone !== undefined) patch.stoneColor = data.color_stone as string;
if (data.description !== undefined) patch.description = data.description as string;
if (data.sum !== undefined) {
const sum = Number(data.sum);
if (!Number.isInteger(sum) || sum < 1) throw new BadRequestException('تعداد باید عدد صحیح و حداقل ۱ باشد');
patch.quantity = sum;
}
if (data.estimatedWeightGrams !== undefined) {
patch.estimatedWeightGrams = new Prisma.Decimal(data.estimatedWeightGrams as string);
}