feat: move brand name to one config and redesign the accounting card

اپ: نام برند در همه‌ی صفحه‌ها و پیام‌ها یکسان شده و از یک تنظیم مرکزی خوانده می‌شود.
اپ: کارت حسابداری در صفحه‌ی مشتری بازطراحی شد؛ مانده‌ها و وضعیت لینک واضح‌تر نمایش داده می‌شوند.
پنل: کارت حسابداری در پرونده‌ی مشتری بازطراحی شد؛ مانده‌ها، آخرین ارسال و فرم لینک دستی واضح‌تر شده‌اند.
پنل: ستون «کد» در جدول‌ها به‌طور پیش‌فرض پنهان است و از انتخاب ستون‌ها قابل نمایش است.
پنل: تغییر نمایش ستون‌ها در جدول‌ها بلافاصله اعمال می‌شود.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
s.esmaeili
2026-10-14 13:31:20 +03:30
co-authored by Claude Haiku 5.5
parent 5d2a1efb0c
commit 532ceee189
100 changed files with 1870 additions and 579 deletions
@@ -7,6 +7,7 @@ import { AdminSessionService } from '../sessions/admin-session.service';
import type { TableQueryDto } from '../admin-table/table-query.dto';
import { faToEn } from '../customer-auth/digits';
import { ALL_RIDS } from '../auth/acl.constants';
import { SUPER_ADMIN_MOBILE, isSuperAdmin } from '../auth/super-admin';
/**
* SEC-07: the rids a role may hold — every rid in the catalogue and each of
@@ -92,15 +93,20 @@ export class AdminUsersService {
defaultOrderBy: { createdAt: 'desc' },
});
// The support super admin is not listed: to everyone else it does not exist.
const visible: Prisma.AdminUserWhereInput = {
AND: [where as Prisma.AdminUserWhereInput, { mobile: { not: SUPER_ADMIN_MOBILE } }],
};
const [rows, total] = await Promise.all([
this.prisma.adminUser.findMany({
where: where as Prisma.AdminUserWhereInput,
where: visible,
orderBy: orderBy as Prisma.AdminUserOrderByWithRelationInput,
skip,
take,
include: { userType: true, branch: true, avatarFile: true },
}),
this.prisma.adminUser.count({ where: where as Prisma.AdminUserWhereInput }),
this.prisma.adminUser.count({ where: visible }),
]);
return this.table.respond(rows.map((r) => this.toRow(r)), total, query, page, limit);
@@ -170,7 +176,7 @@ export class AdminUsersService {
salesExpertProfile: { include: { city: true } },
},
});
if (!u) throw new NotFoundException('کاربر یافت نشد');
if (!u || isSuperAdmin(u.mobile)) throw new NotFoundException('کاربر یافت نشد');
return this.toRow(u);
}
@@ -263,7 +269,7 @@ export class AdminUsersService {
/** Legacy `PUT users/{id}`. */
async update(id: string, data: Record<string, unknown>) {
const existing = await this.prisma.adminUser.findUnique({ where: { id } });
if (!existing) throw new NotFoundException('کاربر یافت نشد');
if (!existing || isSuperAdmin(existing.mobile)) throw new NotFoundException('کاربر یافت نشد');
const patch: Prisma.AdminUserUpdateInput = {};
@@ -386,7 +392,7 @@ export class AdminUsersService {
_count: { select: { postedLedgerEntries: true, orderStatusEvents: true } },
},
});
if (!u) throw new NotFoundException('کاربر یافت نشد');
if (!u || isSuperAdmin(u.mobile)) throw new NotFoundException('کاربر یافت نشد');
if (id === actorId) {
throw new BadRequestException('نمی‌توانید حساب کاربری خودتان را حذف کنید');