rename: کاریز فروش → مسیر فروش, کاریز پروژه → تابلوی پروژه
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,2 @@
|
|||||||
|
-- Rename the default sales pipeline: «کاریز فروش» → «مسیر فروش»
|
||||||
|
UPDATE "Pipeline" SET "name" = 'مسیر فروش' WHERE "name" = 'کاریز فروش';
|
||||||
@@ -1231,7 +1231,7 @@ model PortalOtp {
|
|||||||
@@index([expiresAt])
|
@@index([expiresAt])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// برد کانبان برای کارهای داخلی / پسازفروش (جدا از کاریز فروش)
|
/// برد کانبان برای کارهای داخلی / پسازفروش (جدا از مسیر فروش)
|
||||||
model ProjectBoard {
|
model ProjectBoard {
|
||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
organizationId String
|
organizationId String
|
||||||
@@ -1775,7 +1775,7 @@ model AuditLog {
|
|||||||
@@index([organizationId, entityType, createdAt])
|
@@index([organizationId, entityType, createdAt])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// فیلترهای ذخیرهشده برای لیستها و کاریزها
|
/// فیلترهای ذخیرهشده برای لیستها و مسیرهای فروش
|
||||||
/// ستونهای مخفی هر جدول برای هر کاربر (بهازای هر سازمان)
|
/// ستونهای مخفی هر جدول برای هر کاربر (بهازای هر سازمان)
|
||||||
model UserTablePreference {
|
model UserTablePreference {
|
||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
|
|||||||
+10
-10
@@ -335,7 +335,7 @@ async function main() {
|
|||||||
pipeline = await prisma.pipeline.create({
|
pipeline = await prisma.pipeline.create({
|
||||||
data: {
|
data: {
|
||||||
organizationId: org.id,
|
organizationId: org.id,
|
||||||
name: 'کاریز فروش',
|
name: 'مسیر فروش',
|
||||||
isDefault: true,
|
isDefault: true,
|
||||||
stages: {
|
stages: {
|
||||||
create: DEFAULT_STAGES.map((s, index) => ({
|
create: DEFAULT_STAGES.map((s, index) => ({
|
||||||
@@ -354,13 +354,13 @@ async function main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const servicesPipeline = await prisma.pipeline.findFirst({
|
const servicesPipeline = await prisma.pipeline.findFirst({
|
||||||
where: { organizationId: org.id, name: 'کاریز خدمات' },
|
where: { organizationId: org.id, name: 'مسیر خدمات' },
|
||||||
});
|
});
|
||||||
if (!servicesPipeline) {
|
if (!servicesPipeline) {
|
||||||
await prisma.pipeline.create({
|
await prisma.pipeline.create({
|
||||||
data: {
|
data: {
|
||||||
organizationId: org.id,
|
organizationId: org.id,
|
||||||
name: 'کاریز خدمات',
|
name: 'مسیر خدمات',
|
||||||
isDefault: false,
|
isDefault: false,
|
||||||
stages: {
|
stages: {
|
||||||
create: DEFAULT_STAGES.map((s, index) => ({
|
create: DEFAULT_STAGES.map((s, index) => ({
|
||||||
@@ -377,7 +377,7 @@ async function main() {
|
|||||||
console.log('Services pipeline already seeded');
|
console.log('Services pipeline already seeded');
|
||||||
}
|
}
|
||||||
|
|
||||||
// کاریز منتظر — مطابق طراحی UI (۳ مرحله + معاملات نمونه)
|
// مسیر منتظر — مطابق طراحی UI (۳ مرحله + معاملات نمونه)
|
||||||
const WAITING_STAGES = [
|
const WAITING_STAGES = [
|
||||||
{ name: 'پیگیری', isWon: false, isLost: false },
|
{ name: 'پیگیری', isWon: false, isLost: false },
|
||||||
{ name: 'مذاکرات اولیه', isWon: false, isLost: false },
|
{ name: 'مذاکرات اولیه', isWon: false, isLost: false },
|
||||||
@@ -483,7 +483,7 @@ async function main() {
|
|||||||
];
|
];
|
||||||
|
|
||||||
let waitingPipeline = await prisma.pipeline.findFirst({
|
let waitingPipeline = await prisma.pipeline.findFirst({
|
||||||
where: { organizationId: org.id, name: 'کاریز منتظر' },
|
where: { organizationId: org.id, name: 'مسیر منتظر' },
|
||||||
include: { stages: { orderBy: { position: 'asc' } } },
|
include: { stages: { orderBy: { position: 'asc' } } },
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -491,7 +491,7 @@ async function main() {
|
|||||||
waitingPipeline = await prisma.pipeline.create({
|
waitingPipeline = await prisma.pipeline.create({
|
||||||
data: {
|
data: {
|
||||||
organizationId: org.id,
|
organizationId: org.id,
|
||||||
name: 'کاریز منتظر',
|
name: 'مسیر منتظر',
|
||||||
isDefault: false,
|
isDefault: false,
|
||||||
stages: {
|
stages: {
|
||||||
create: WAITING_STAGES.map((s, index) => ({
|
create: WAITING_STAGES.map((s, index) => ({
|
||||||
@@ -504,7 +504,7 @@ async function main() {
|
|||||||
},
|
},
|
||||||
include: { stages: { orderBy: { position: 'asc' } } },
|
include: { stages: { orderBy: { position: 'asc' } } },
|
||||||
});
|
});
|
||||||
console.log('Seeded waiting pipeline (کاریز منتظر)');
|
console.log('Seeded waiting pipeline (مسیر منتظر)');
|
||||||
} else {
|
} else {
|
||||||
console.log('Waiting pipeline already seeded');
|
console.log('Waiting pipeline already seeded');
|
||||||
}
|
}
|
||||||
@@ -534,7 +534,7 @@ async function main() {
|
|||||||
expectedCloseAt: new Date(d.expectedCloseAt),
|
expectedCloseAt: new Date(d.expectedCloseAt),
|
||||||
ownerId: owner?.id,
|
ownerId: owner?.id,
|
||||||
position: d.position,
|
position: d.position,
|
||||||
tags: ['دمو-کاریز'],
|
tags: ['دمو-مسیر'],
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
@@ -763,7 +763,7 @@ async function main() {
|
|||||||
{
|
{
|
||||||
organizationId: org.id,
|
organizationId: org.id,
|
||||||
authorId: owner?.id,
|
authorId: owner?.id,
|
||||||
body: 'در دمو نوا روی گزارش کاریز خیلی حساس بودند. نسخه چاپی PDF را آماده کنیم.',
|
body: 'در دمو نوا روی گزارش مسیر فروش خیلی حساس بودند. نسخه چاپی PDF را آماده کنیم.',
|
||||||
noteType: 'call_result',
|
noteType: 'call_result',
|
||||||
color: 'sky',
|
color: 'sky',
|
||||||
tags: ['دمو'],
|
tags: ['دمو'],
|
||||||
@@ -971,7 +971,7 @@ async function main() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
await ensure('deal_moved', {
|
await ensure('deal_moved', {
|
||||||
title: 'جابهجایی معامله در کاریز',
|
title: 'جابهجایی معامله در مسیر فروش',
|
||||||
body: sampleDeal
|
body: sampleDeal
|
||||||
? `«${sampleDeal.title}» به مرحله جدید منتقل شد`
|
? `«${sampleDeal.title}» به مرحله جدید منتقل شد`
|
||||||
: 'یک معامله جابهجا شد',
|
: 'یک معامله جابهجا شد',
|
||||||
|
|||||||
@@ -677,7 +677,7 @@ export class LeadFormsService {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
if (!pipeline?.stages.length) {
|
if (!pipeline?.stages.length) {
|
||||||
throw new BadRequestException('کاریز فعالی برای ثبت معامله وجود ندارد');
|
throw new BadRequestException('مسیر فروش فعالی برای ثبت معامله وجود ندارد');
|
||||||
}
|
}
|
||||||
|
|
||||||
const stage =
|
const stage =
|
||||||
@@ -744,7 +744,7 @@ export class LeadFormsService {
|
|||||||
where: { id, organizationId },
|
where: { id, organizationId },
|
||||||
select: { id: true },
|
select: { id: true },
|
||||||
});
|
});
|
||||||
if (!found) throw new BadRequestException('کاریز انتخابشده معتبر نیست');
|
if (!found) throw new BadRequestException('مسیر فروش انتخابشده معتبر نیست');
|
||||||
}
|
}
|
||||||
|
|
||||||
private async assertLeadStage(
|
private async assertLeadStage(
|
||||||
|
|||||||
@@ -502,7 +502,7 @@ export class DealsExcelService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* مراحل پیشفرض سیستم (سرنخ، تماس اول، …) که خالی ماندهاند از کاریزهای واردشده حذف میشوند
|
* مراحل پیشفرض سیستم (سرنخ، تماس اول، …) که خالی ماندهاند از مسیرهای فروش واردشده حذف میشوند
|
||||||
* تا فقط مراحل خود فایل دیده شوند.
|
* تا فقط مراحل خود فایل دیده شوند.
|
||||||
*/
|
*/
|
||||||
private async removeUnusedDefaultStages(organizationId: string, pipelineIds: Set<string>) {
|
private async removeUnusedDefaultStages(organizationId: string, pipelineIds: Set<string>) {
|
||||||
@@ -634,7 +634,8 @@ export class DealsExcelService {
|
|||||||
status: DealStatus,
|
status: DealStatus,
|
||||||
ctx: RowContext,
|
ctx: RowContext,
|
||||||
) {
|
) {
|
||||||
const name = pipelineName?.trim() || 'کاریز فروش';
|
const rawName = pipelineName?.trim();
|
||||||
|
const name = !rawName || rawName === 'کاریز فروش' ? 'مسیر فروش' : rawName;
|
||||||
const cacheKey = name.toLowerCase();
|
const cacheKey = name.toLowerCase();
|
||||||
let pipeline = ctx.pipelines.get(cacheKey);
|
let pipeline = ctx.pipelines.get(cacheKey);
|
||||||
if (!pipeline) {
|
if (!pipeline) {
|
||||||
@@ -677,7 +678,7 @@ export class DealsExcelService {
|
|||||||
}
|
}
|
||||||
const added = await this.pipelines.createStage(organizationId, pipeline.id, wanted);
|
const added = await this.pipelines.createStage(organizationId, pipeline.id, wanted);
|
||||||
const stage = added.stages.find((s) => s.name === wanted) ?? added.stages.at(-1);
|
const stage = added.stages.find((s) => s.name === wanted) ?? added.stages.at(-1);
|
||||||
if (!stage) throw new Error('کاریز مرحلهای ندارد');
|
if (!stage) throw new Error('مسیر فروش مرحلهای ندارد');
|
||||||
pipeline.stages = added.stages.map((s) => ({
|
pipeline.stages = added.stages.map((s) => ({
|
||||||
id: s.id,
|
id: s.id,
|
||||||
name: s.name,
|
name: s.name,
|
||||||
@@ -688,7 +689,7 @@ export class DealsExcelService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const stage = byStatusExisting ?? pipeline.stages[0];
|
const stage = byStatusExisting ?? pipeline.stages[0];
|
||||||
if (!stage) throw new Error('کاریز مرحلهای ندارد');
|
if (!stage) throw new Error('مسیر فروش مرحلهای ندارد');
|
||||||
return { pipelineId: pipeline.id, stageId: stage.id, pipelineName: pipeline.name };
|
return { pipelineId: pipeline.id, stageId: stage.id, pipelineName: pipeline.name };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ export class DealsService {
|
|||||||
resolvedPipeline.stages[0];
|
resolvedPipeline.stages[0];
|
||||||
|
|
||||||
if (!stage) {
|
if (!stage) {
|
||||||
throw new BadRequestException('کاریز مرحلهای ندارد');
|
throw new BadRequestException('مسیر فروش مرحلهای ندارد');
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.assertLinks(organizationId, actor, dto.personId, dto.companyId);
|
await this.assertLinks(organizationId, actor, dto.personId, dto.companyId);
|
||||||
@@ -337,7 +337,7 @@ export class DealsService {
|
|||||||
where: { id: dto.stageId, pipelineId: deal.pipelineId },
|
where: { id: dto.stageId, pipelineId: deal.pipelineId },
|
||||||
});
|
});
|
||||||
if (!stage) {
|
if (!stage) {
|
||||||
throw new BadRequestException('مرحله در این کاریز معتبر نیست');
|
throw new BadRequestException('مرحله در این مسیر فروش معتبر نیست');
|
||||||
}
|
}
|
||||||
|
|
||||||
const status = stage.isWon ? 'won' : stage.isLost ? 'lost' : 'open';
|
const status = stage.isWon ? 'won' : stage.isLost ? 'lost' : 'open';
|
||||||
@@ -369,7 +369,7 @@ export class DealsService {
|
|||||||
organizationId,
|
organizationId,
|
||||||
userId: deal.ownerId,
|
userId: deal.ownerId,
|
||||||
type: 'deal_moved',
|
type: 'deal_moved',
|
||||||
title: 'جابهجایی معامله در کاریز',
|
title: 'جابهجایی معامله در مسیر فروش',
|
||||||
body: `«${deal.title}» به مرحله «${stage.name}» منتقل شد`,
|
body: `«${deal.title}» به مرحله «${stage.name}» منتقل شد`,
|
||||||
link: `/deals/${deal.id}`,
|
link: `/deals/${deal.id}`,
|
||||||
entityType: 'deal',
|
entityType: 'deal',
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ export class PipelinesService {
|
|||||||
const created = await this.prisma.pipeline.create({
|
const created = await this.prisma.pipeline.create({
|
||||||
data: {
|
data: {
|
||||||
organizationId,
|
organizationId,
|
||||||
name: 'کاریز فروش',
|
name: 'مسیر فروش',
|
||||||
isDefault: true,
|
isDefault: true,
|
||||||
stages: {
|
stages: {
|
||||||
create: DEFAULT_STAGES.map((s, index) => ({
|
create: DEFAULT_STAGES.map((s, index) => ({
|
||||||
@@ -389,7 +389,7 @@ export class PipelinesService {
|
|||||||
where: { id: pipelineId, organizationId },
|
where: { id: pipelineId, organizationId },
|
||||||
include: { stages: { orderBy: { position: 'asc' } } },
|
include: { stages: { orderBy: { position: 'asc' } } },
|
||||||
});
|
});
|
||||||
if (!pipeline) throw new NotFoundException('کاریز پیدا نشد');
|
if (!pipeline) throw new NotFoundException('مسیر فروش پیدا نشد');
|
||||||
return pipeline;
|
return pipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ const CASE_COLUMNS = [
|
|||||||
{ header: 'نام خانوادگی شخص کارت', key: 'personName', width: 22 },
|
{ header: 'نام خانوادگی شخص کارت', key: 'personName', width: 22 },
|
||||||
{ header: 'کد دیدار شخص', key: 'personCode', width: 14 },
|
{ header: 'کد دیدار شخص', key: 'personCode', width: 14 },
|
||||||
{ header: 'موبایل شخص کارت', key: 'personMobile', width: 16 },
|
{ header: 'موبایل شخص کارت', key: 'personMobile', width: 16 },
|
||||||
{ header: 'کاریز کارت', key: 'boardName', width: 20 },
|
{ header: 'تابلوی پروژه کارت', key: 'boardName', width: 20 },
|
||||||
{ header: 'مرحله کاریز کارت', key: 'stageName', width: 18 },
|
{ header: 'مرحله تابلوی پروژه کارت', key: 'stageName', width: 18 },
|
||||||
{ header: 'تاریخ انجام کارت', key: 'doneDate', width: 16 },
|
{ header: 'تاریخ انجام کارت', key: 'doneDate', width: 16 },
|
||||||
{ header: 'برچسب', key: 'tag', width: 16 },
|
{ header: 'برچسب', key: 'tag', width: 16 },
|
||||||
];
|
];
|
||||||
@@ -53,6 +53,9 @@ const CASE_ALIASES: Record<string, string> = {
|
|||||||
نامخانوادگیشخصکارت: 'personName',
|
نامخانوادگیشخصکارت: 'personName',
|
||||||
کددیدارشخص: 'personCode',
|
کددیدارشخص: 'personCode',
|
||||||
موبایلشخصکارت: 'personMobile',
|
موبایلشخصکارت: 'personMobile',
|
||||||
|
تابلویپروژهکارت: 'boardName',
|
||||||
|
مرحلهتابلویپروژهکارت: 'stageName',
|
||||||
|
// سرستونهای قدیمی (قبل از تغییر نام کاریز → تابلوی پروژه)
|
||||||
کاریزکارت: 'boardName',
|
کاریزکارت: 'boardName',
|
||||||
مرحلهکاریزکارت: 'stageName',
|
مرحلهکاریزکارت: 'stageName',
|
||||||
تاریخانجامکارت: 'doneDate',
|
تاریخانجامکارت: 'doneDate',
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ const cols = computed<Col[]>(() => {
|
|||||||
|
|
||||||
<HomePanelEmpty
|
<HomePanelEmpty
|
||||||
v-if="!cols.length"
|
v-if="!cols.length"
|
||||||
title="هنوز معاملهای در کاریز نیست"
|
title="هنوز معاملهای در مسیر فروش نیست"
|
||||||
description="اولین معامله را بسازید تا جریان فروش اینجا دیده شود."
|
description="اولین معامله را بسازید تا جریان فروش اینجا دیده شود."
|
||||||
action-label="معامله جدید"
|
action-label="معامله جدید"
|
||||||
:action-to="{ name: 'deal-new' }"
|
:action-to="{ name: 'deal-new' }"
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ withDefaults(
|
|||||||
{
|
{
|
||||||
canCreate: false,
|
canCreate: false,
|
||||||
icon: 'briefcase',
|
icon: 'briefcase',
|
||||||
createOptionLabel: 'کاریز جدید…',
|
createOptionLabel: 'مسیر فروش جدید…',
|
||||||
showAmountFilters: true,
|
showAmountFilters: true,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -34,7 +34,7 @@ const amountMin = defineModel<string>('amountMin', { default: '' });
|
|||||||
const amountMax = defineModel<string>('amountMax', { default: '' });
|
const amountMax = defineModel<string>('amountMax', { default: '' });
|
||||||
|
|
||||||
const viewOptions = [
|
const viewOptions = [
|
||||||
{ value: 'kanban' as const, label: 'نمای کاریز', icon: 'grid' as const },
|
{ value: 'kanban' as const, label: 'نمای ستونی', icon: 'grid' as const },
|
||||||
{ value: 'list' as const, label: 'نمای لیست', icon: 'list' as const },
|
{ value: 'list' as const, label: 'نمای لیست', icon: 'list' as const },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ export const NAV_HUBS: NavHubDef[] = [
|
|||||||
tint: 'sky',
|
tint: 'sky',
|
||||||
shortcuts: [
|
shortcuts: [
|
||||||
{ to: '/leads', title: 'فهرست لیدها', icon: 'users', module: 'leads' },
|
{ to: '/leads', title: 'فهرست لیدها', icon: 'users', module: 'leads' },
|
||||||
{ to: '/leads/board', title: 'کاریز لیدها', icon: 'filter', module: 'leads' },
|
{ to: '/leads/board', title: 'مسیر لیدها', icon: 'filter', module: 'leads' },
|
||||||
],
|
],
|
||||||
cards: [
|
cards: [
|
||||||
{
|
{
|
||||||
@@ -121,8 +121,8 @@ export const NAV_HUBS: NavHubDef[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
to: '/leads/board',
|
to: '/leads/board',
|
||||||
title: 'کاریز لیدها',
|
title: 'مسیر لیدها',
|
||||||
desc: 'نمای کانبان و حرکت بین مراحل',
|
desc: 'نمای ستونی و حرکت بین مراحل',
|
||||||
icon: 'filter',
|
icon: 'filter',
|
||||||
tint: 'violet',
|
tint: 'violet',
|
||||||
module: 'leads',
|
module: 'leads',
|
||||||
@@ -130,7 +130,7 @@ export const NAV_HUBS: NavHubDef[] = [
|
|||||||
{
|
{
|
||||||
to: '/settings/lead-stages',
|
to: '/settings/lead-stages',
|
||||||
title: 'مراحل و وضعیتها',
|
title: 'مراحل و وضعیتها',
|
||||||
desc: 'تعریف وضعیتها و ستونهای کاریز لید',
|
desc: 'تعریف وضعیتها و ستونهای مسیر لید',
|
||||||
icon: 'layers',
|
icon: 'layers',
|
||||||
tint: 'peach',
|
tint: 'peach',
|
||||||
admin: true,
|
admin: true,
|
||||||
@@ -160,7 +160,7 @@ export const NAV_HUBS: NavHubDef[] = [
|
|||||||
cards: [
|
cards: [
|
||||||
{
|
{
|
||||||
to: '/pipeline',
|
to: '/pipeline',
|
||||||
title: 'کاریز فروش',
|
title: 'مسیر فروش',
|
||||||
desc: 'معاملات و مراحل فروش',
|
desc: 'معاملات و مراحل فروش',
|
||||||
icon: 'filter',
|
icon: 'filter',
|
||||||
tint: 'mint',
|
tint: 'mint',
|
||||||
@@ -329,7 +329,7 @@ export const NAV_HUBS: NavHubDef[] = [
|
|||||||
cards: [
|
cards: [
|
||||||
{
|
{
|
||||||
to: '/projects',
|
to: '/projects',
|
||||||
title: 'کاریز پروژه',
|
title: 'تابلوی پروژه',
|
||||||
desc: 'میز کار تیمی: صف، انجام، بازبینی و ارجاع کارت',
|
desc: 'میز کار تیمی: صف، انجام، بازبینی و ارجاع کارت',
|
||||||
icon: 'flag',
|
icon: 'flag',
|
||||||
tint: 'violet',
|
tint: 'violet',
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ export function currencyUnitLabel(currency: string): string {
|
|||||||
return currency;
|
return currency;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** نگاشت برد API به مدل UI کاریز */
|
/** نگاشت برد API به مدل UI مسیر فروش */
|
||||||
export function mapBoardToStages(
|
export function mapBoardToStages(
|
||||||
board: {
|
board: {
|
||||||
stages: Array<{
|
stages: Array<{
|
||||||
|
|||||||
@@ -435,7 +435,7 @@ onMounted(load);
|
|||||||
>
|
>
|
||||||
<template #lead>
|
<template #lead>
|
||||||
<span class="crumb">
|
<span class="crumb">
|
||||||
<RouterLink :to="{ name: 'pipeline' }">کاریز فروش</RouterLink>
|
<RouterLink :to="{ name: 'pipeline' }">مسیر فروش</RouterLink>
|
||||||
<span>›</span>
|
<span>›</span>
|
||||||
<strong>{{ pageTitle }}</strong>
|
<strong>{{ pageTitle }}</strong>
|
||||||
</span>
|
</span>
|
||||||
@@ -678,13 +678,13 @@ onMounted(load);
|
|||||||
</UiSelect>
|
</UiSelect>
|
||||||
</UiField>
|
</UiField>
|
||||||
|
|
||||||
<UiField label="کاریز فروش">
|
<UiField label="مسیر فروش">
|
||||||
<UiSelect :model-value="pipelineId" @update:model-value="onPipelineChange($event)">
|
<UiSelect :model-value="pipelineId" @update:model-value="onPipelineChange($event)">
|
||||||
<option v-for="p in pipelines" :key="p.id" :value="p.id">{{ p.name }}</option>
|
<option v-for="p in pipelines" :key="p.id" :value="p.id">{{ p.name }}</option>
|
||||||
</UiSelect>
|
</UiSelect>
|
||||||
</UiField>
|
</UiField>
|
||||||
|
|
||||||
<UiField label="مرحله کاریز" required>
|
<UiField label="مرحله" required>
|
||||||
<UiSelect v-model="stageId" required>
|
<UiSelect v-model="stageId" required>
|
||||||
<option v-for="s in stages" :key="s.id" :value="s.id">{{ s.name }}</option>
|
<option v-for="s in stages" :key="s.id" :value="s.id">{{ s.name }}</option>
|
||||||
</UiSelect>
|
</UiSelect>
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ async function load() {
|
|||||||
error.value =
|
error.value =
|
||||||
axios.isAxiosError(e) && !e.response
|
axios.isAxiosError(e) && !e.response
|
||||||
? 'اتصال به API برقرار نشد.'
|
? 'اتصال به API برقرار نشد.'
|
||||||
: 'بارگذاری کاریز لیدها ناموفق بود.';
|
: 'بارگذاری مسیر لیدها ناموفق بود.';
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
@@ -107,7 +107,7 @@ onMounted(load);
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<section class="page">
|
<section class="page">
|
||||||
<UiPageHeader title="کاریز لیدها" lead="کشیدن و رها کردن برای تغییر وضعیت">
|
<UiPageHeader title="مسیر لیدها" lead="کشیدن و رها کردن برای تغییر وضعیت">
|
||||||
<template #actions>
|
<template #actions>
|
||||||
<RouterLink :to="{ name: 'leads' }" class="link-btn">
|
<RouterLink :to="{ name: 'leads' }" class="link-btn">
|
||||||
<UiButton variant="ghost" size="sm">فهرست لیدها</UiButton>
|
<UiButton variant="ghost" size="sm">فهرست لیدها</UiButton>
|
||||||
@@ -166,8 +166,8 @@ onMounted(load);
|
|||||||
|
|
||||||
<UiEmptyState
|
<UiEmptyState
|
||||||
v-else-if="!loading"
|
v-else-if="!loading"
|
||||||
title="مرحلهای برای کاریز نیست."
|
title="مرحلهای برای نمایش در مسیر لیدها نیست."
|
||||||
description="در تنظیمات مراحل لید، نمایش روی کاریز را فعال کنید."
|
description="در تنظیمات مراحل لید، «نمایش روی مسیر» را فعال کنید."
|
||||||
/>
|
/>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -594,7 +594,7 @@ onMounted(load);
|
|||||||
<input v-model="createDeal" type="checkbox" />
|
<input v-model="createDeal" type="checkbox" />
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<label v-if="createDeal" class="field pipeline-field">کاریز مقصد
|
<label v-if="createDeal" class="field pipeline-field">مسیر فروش مقصد
|
||||||
<select v-model="pipelineId">
|
<select v-model="pipelineId">
|
||||||
<option value="">پیشفرض سازمان</option>
|
<option value="">پیشفرض سازمان</option>
|
||||||
<option v-for="p in pipelines" :key="p.id" :value="p.id">{{ p.name }}</option>
|
<option v-for="p in pipelines" :key="p.id" :value="p.id">{{ p.name }}</option>
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ onMounted(load);
|
|||||||
<section class="crm-page">
|
<section class="crm-page">
|
||||||
<UiPageHeader
|
<UiPageHeader
|
||||||
title="مراحل لید"
|
title="مراحل لید"
|
||||||
lead="تعریف وضعیتهای کاریز لیدها و برچسبهای تبدیل/از دسترفته"
|
lead="تعریف وضعیتهای مسیر لیدها و برچسبهای تبدیل/از دسترفته"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<p v-if="okMsg" class="ok">{{ okMsg }}</p>
|
<p v-if="okMsg" class="ok">{{ okMsg }}</p>
|
||||||
@@ -194,7 +194,7 @@ onMounted(load);
|
|||||||
</UiField>
|
</UiField>
|
||||||
<label class="check">
|
<label class="check">
|
||||||
<input v-model="showOnBoard" type="checkbox" />
|
<input v-model="showOnBoard" type="checkbox" />
|
||||||
نمایش روی کاریز
|
نمایش روی مسیر
|
||||||
</label>
|
</label>
|
||||||
<label class="check">
|
<label class="check">
|
||||||
<input v-model="isConverted" type="checkbox" />
|
<input v-model="isConverted" type="checkbox" />
|
||||||
@@ -227,7 +227,7 @@ onMounted(load);
|
|||||||
</UiField>
|
</UiField>
|
||||||
<label class="check">
|
<label class="check">
|
||||||
<input v-model="editShowOnBoard" type="checkbox" />
|
<input v-model="editShowOnBoard" type="checkbox" />
|
||||||
نمایش روی کاریز
|
نمایش روی مسیر
|
||||||
</label>
|
</label>
|
||||||
<label class="check">
|
<label class="check">
|
||||||
<input v-model="editConverted" type="checkbox" />
|
<input v-model="editConverted" type="checkbox" />
|
||||||
@@ -253,7 +253,7 @@ onMounted(load);
|
|||||||
<div class="info">
|
<div class="info">
|
||||||
<strong>{{ stage.name }}</strong>
|
<strong>{{ stage.name }}</strong>
|
||||||
<span class="muted">
|
<span class="muted">
|
||||||
{{ stage.showOnBoard ? 'روی کاریز' : 'مخفی از کاریز' }}
|
{{ stage.showOnBoard ? 'روی مسیر' : 'مخفی از مسیر' }}
|
||||||
<template v-if="stage.leadCount != null">
|
<template v-if="stage.leadCount != null">
|
||||||
· {{ toFaDigits(stage.leadCount) }} لید
|
· {{ toFaDigits(stage.leadCount) }} لید
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1230,11 +1230,11 @@ onBeforeUnmount(() => {
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<TableColumnsMenu table-key="leads" align="end" />
|
<TableColumnsMenu table-key="leads" align="end" />
|
||||||
<div class="view-toggle" title="نمای لیست / کاریز">
|
<div class="view-toggle" title="نمای لیست / مسیر">
|
||||||
<button type="button" class="view-btn on" title="لیست">
|
<button type="button" class="view-btn on" title="لیست">
|
||||||
<UiIcon name="list" :size="16" />
|
<UiIcon name="list" :size="16" />
|
||||||
</button>
|
</button>
|
||||||
<RouterLink class="view-btn" :to="{ name: 'leads-board' }" title="کاریز">
|
<RouterLink class="view-btn" :to="{ name: 'leads-board' }" title="مسیر لیدها">
|
||||||
<UiIcon name="grid" :size="16" />
|
<UiIcon name="grid" :size="16" />
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -870,7 +870,7 @@ watch(() => route.query.tab, readTab, { immediate: true });
|
|||||||
<ProfileEmptyState
|
<ProfileEmptyState
|
||||||
v-if="dealsEmpty"
|
v-if="dealsEmpty"
|
||||||
title="هنوز معاملهای ثبت نشده!"
|
title="هنوز معاملهای ثبت نشده!"
|
||||||
description="اولین معامله این مشتری را در کاریز ثبت کنید یا یک فعالیت پیگیری بسازید."
|
description="اولین معامله این مشتری را در مسیر فروش ثبت کنید یا یک فعالیت پیگیری بسازید."
|
||||||
primary-label="افزودن معامله"
|
primary-label="افزودن معامله"
|
||||||
:primary-to="{ name: 'deal-new', query: { personId: id } }"
|
:primary-to="{ name: 'deal-new', query: { personId: id } }"
|
||||||
secondary-label="افزودن اولین فعالیت"
|
secondary-label="افزودن اولین فعالیت"
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ async function load() {
|
|||||||
if (axios.isAxiosError(e) && !e.response) {
|
if (axios.isAxiosError(e) && !e.response) {
|
||||||
error.value = 'اتصال به API برقرار نشد.';
|
error.value = 'اتصال به API برقرار نشد.';
|
||||||
} else {
|
} else {
|
||||||
error.value = 'بارگذاری کاریز ناموفق بود.';
|
error.value = 'بارگذاری مسیر فروش ناموفق بود.';
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
@@ -189,7 +189,7 @@ async function createPipeline() {
|
|||||||
showCreate.value = false;
|
showCreate.value = false;
|
||||||
await router.replace({ name: 'pipeline', query: { pipelineId: data.id } });
|
await router.replace({ name: 'pipeline', query: { pipelineId: data.id } });
|
||||||
} catch {
|
} catch {
|
||||||
error.value = 'ساخت کاریز ناموفق بود.';
|
error.value = 'ساخت مسیر فروش ناموفق بود.';
|
||||||
} finally {
|
} finally {
|
||||||
saving.value = false;
|
saving.value = false;
|
||||||
}
|
}
|
||||||
@@ -451,7 +451,7 @@ function onImportStart() {
|
|||||||
async function onImportDone(data: ImportContactsResult) {
|
async function onImportDone(data: ImportContactsResult) {
|
||||||
importMsg.value = `وارد شد: ${data.created} · تکراری رد شد: ${data.skipped}${
|
importMsg.value = `وارد شد: ${data.created} · تکراری رد شد: ${data.skipped}${
|
||||||
data.errors.length ? ` · خطا: ${data.errors.length}` : ''
|
data.errors.length ? ` · خطا: ${data.errors.length}` : ''
|
||||||
}${data.boards?.length ? ` · کاریز: ${data.boards.join('، ')}` : ''}`;
|
}${data.boards?.length ? ` · مسیر فروش: ${data.boards.join('، ')}` : ''}`;
|
||||||
if (data.errors.length) {
|
if (data.errors.length) {
|
||||||
error.value = data.errors
|
error.value = data.errors
|
||||||
.slice(0, 3)
|
.slice(0, 3)
|
||||||
@@ -504,7 +504,7 @@ defineExpose({ updateDealStage: applyUpdateDealStage });
|
|||||||
<section class="page" dir="rtl">
|
<section class="page" dir="rtl">
|
||||||
<UiBusyOverlay :open="pageBusy" :message="busyMessage" />
|
<UiBusyOverlay :open="pageBusy" :message="busyMessage" />
|
||||||
<PipelineToolbar
|
<PipelineToolbar
|
||||||
pipeline-name="کاریز فروش"
|
pipeline-name="مسیر فروش"
|
||||||
:pipeline-options="pipelineOptions"
|
:pipeline-options="pipelineOptions"
|
||||||
v-model:selected-pipeline-id="selectedPipelineId"
|
v-model:selected-pipeline-id="selectedPipelineId"
|
||||||
v-model:view-mode="viewMode"
|
v-model:view-mode="viewMode"
|
||||||
@@ -546,7 +546,7 @@ defineExpose({ updateDealStage: applyUpdateDealStage });
|
|||||||
|
|
||||||
<p v-if="error" class="error">{{ error }}</p>
|
<p v-if="error" class="error">{{ error }}</p>
|
||||||
<p v-if="importMsg" class="ok">{{ importMsg }}</p>
|
<p v-if="importMsg" class="ok">{{ importMsg }}</p>
|
||||||
<p v-else-if="loading && !stages.length" class="muted">در حال بارگذاری کاریز…</p>
|
<p v-else-if="loading && !stages.length" class="muted">در حال بارگذاری مسیر فروش…</p>
|
||||||
|
|
||||||
<PipelineList
|
<PipelineList
|
||||||
v-if="viewMode === 'list' && (!loading || stages.length)"
|
v-if="viewMode === 'list' && (!loading || stages.length)"
|
||||||
@@ -602,15 +602,15 @@ defineExpose({ updateDealStage: applyUpdateDealStage });
|
|||||||
|
|
||||||
<UiModal
|
<UiModal
|
||||||
:open="showCreate && canCreatePipeline"
|
:open="showCreate && canCreatePipeline"
|
||||||
title="کاریز جدید"
|
title="مسیر فروش جدید"
|
||||||
@close="showCreate = false"
|
@close="showCreate = false"
|
||||||
>
|
>
|
||||||
<form class="create-form" @submit.prevent="createPipeline">
|
<form class="create-form" @submit.prevent="createPipeline">
|
||||||
<label class="field">
|
<label class="field">
|
||||||
<span>نام کاریز</span>
|
<span>نام مسیر فروش</span>
|
||||||
<UiInput
|
<UiInput
|
||||||
v-model="newName"
|
v-model="newName"
|
||||||
placeholder="نام کاریز جدید…"
|
placeholder="نام مسیر فروش جدید…"
|
||||||
:maxlength="120"
|
:maxlength="120"
|
||||||
required
|
required
|
||||||
:minlength="2"
|
:minlength="2"
|
||||||
|
|||||||
@@ -647,7 +647,7 @@ watch(
|
|||||||
<ProfileEmptyState
|
<ProfileEmptyState
|
||||||
v-if="dealsEmpty"
|
v-if="dealsEmpty"
|
||||||
title="هنوز معاملهای ثبت نشده!"
|
title="هنوز معاملهای ثبت نشده!"
|
||||||
description="اولین معامله را در کاریز ثبت کنید یا یک فعالیت پیگیری بسازید."
|
description="اولین معامله را در مسیر فروش ثبت کنید یا یک فعالیت پیگیری بسازید."
|
||||||
primary-label="افزودن معامله"
|
primary-label="افزودن معامله"
|
||||||
:primary-to="{ name: 'deal-new' }"
|
:primary-to="{ name: 'deal-new' }"
|
||||||
secondary-label="افزودن اولین فعالیت"
|
secondary-label="افزودن اولین فعالیت"
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ async function load() {
|
|||||||
if (axios.isAxiosError(e) && !e.response) {
|
if (axios.isAxiosError(e) && !e.response) {
|
||||||
error.value = 'اتصال به API برقرار نشد.';
|
error.value = 'اتصال به API برقرار نشد.';
|
||||||
} else {
|
} else {
|
||||||
error.value = 'بارگذاری برد پروژه ناموفق بود.';
|
error.value = 'بارگذاری تابلوی پروژه ناموفق بود.';
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
@@ -164,7 +164,7 @@ async function createBoard() {
|
|||||||
showCreate.value = false;
|
showCreate.value = false;
|
||||||
await router.replace({ name: 'projects', query: { boardId: data.id } });
|
await router.replace({ name: 'projects', query: { boardId: data.id } });
|
||||||
} catch {
|
} catch {
|
||||||
error.value = 'ساخت برد ناموفق بود.';
|
error.value = 'ساخت تابلو ناموفق بود.';
|
||||||
} finally {
|
} finally {
|
||||||
saving.value = false;
|
saving.value = false;
|
||||||
}
|
}
|
||||||
@@ -417,7 +417,7 @@ function onImportStart() {
|
|||||||
async function onImportDone(data: ImportContactsResult) {
|
async function onImportDone(data: ImportContactsResult) {
|
||||||
importMsg.value = `وارد شد: ${data.created} · تکراری رد شد: ${data.skipped}${
|
importMsg.value = `وارد شد: ${data.created} · تکراری رد شد: ${data.skipped}${
|
||||||
data.errors.length ? ` · خطا: ${data.errors.length}` : ''
|
data.errors.length ? ` · خطا: ${data.errors.length}` : ''
|
||||||
}${data.boards?.length ? ` · برد: ${data.boards.join('، ')}` : ''}`;
|
}${data.boards?.length ? ` · تابلو: ${data.boards.join('، ')}` : ''}`;
|
||||||
if (data.errors.length) {
|
if (data.errors.length) {
|
||||||
error.value = data.errors
|
error.value = data.errors
|
||||||
.slice(0, 3)
|
.slice(0, 3)
|
||||||
@@ -468,9 +468,9 @@ onBeforeUnmount(() => {
|
|||||||
<section class="page" dir="rtl">
|
<section class="page" dir="rtl">
|
||||||
<UiBusyOverlay :open="pageBusy" :message="busyMessage" />
|
<UiBusyOverlay :open="pageBusy" :message="busyMessage" />
|
||||||
<PipelineToolbar
|
<PipelineToolbar
|
||||||
pipeline-name="کاریز پروژه — کارهای تیمی"
|
pipeline-name="تابلوی پروژه — کارهای تیمی"
|
||||||
icon="grid"
|
icon="grid"
|
||||||
create-option-label="برد جدید…"
|
create-option-label="تابلوی جدید…"
|
||||||
:pipeline-options="boardOptions"
|
:pipeline-options="boardOptions"
|
||||||
v-model:selected-pipeline-id="selectedBoardId"
|
v-model:selected-pipeline-id="selectedBoardId"
|
||||||
v-model:view-mode="viewMode"
|
v-model:view-mode="viewMode"
|
||||||
@@ -505,7 +505,7 @@ onBeforeUnmount(() => {
|
|||||||
|
|
||||||
<p v-if="error" class="error">{{ error }}</p>
|
<p v-if="error" class="error">{{ error }}</p>
|
||||||
<p v-if="importMsg" class="ok">{{ importMsg }}</p>
|
<p v-if="importMsg" class="ok">{{ importMsg }}</p>
|
||||||
<p v-else-if="loading && !stages.length" class="muted">در حال بارگذاری برد…</p>
|
<p v-else-if="loading && !stages.length" class="muted">در حال بارگذاری تابلو…</p>
|
||||||
|
|
||||||
<PipelineList
|
<PipelineList
|
||||||
v-if="viewMode === 'list' && (!loading || stages.length)"
|
v-if="viewMode === 'list' && (!loading || stages.length)"
|
||||||
@@ -564,15 +564,15 @@ onBeforeUnmount(() => {
|
|||||||
|
|
||||||
<UiModal
|
<UiModal
|
||||||
:open="showCreate && canCreateBoard"
|
:open="showCreate && canCreateBoard"
|
||||||
title="برد جدید"
|
title="تابلوی جدید"
|
||||||
@close="showCreate = false"
|
@close="showCreate = false"
|
||||||
>
|
>
|
||||||
<form class="create-form" @submit.prevent="createBoard">
|
<form class="create-form" @submit.prevent="createBoard">
|
||||||
<label class="field">
|
<label class="field">
|
||||||
<span>نام برد</span>
|
<span>نام تابلو</span>
|
||||||
<UiInput
|
<UiInput
|
||||||
v-model="newName"
|
v-model="newName"
|
||||||
placeholder="نام برد جدید…"
|
placeholder="نام تابلوی جدید…"
|
||||||
:maxlength="120"
|
:maxlength="120"
|
||||||
required
|
required
|
||||||
:minlength="2"
|
:minlength="2"
|
||||||
|
|||||||
@@ -1404,7 +1404,7 @@ const activityMax = computed(() =>
|
|||||||
|
|
||||||
<!-- Deep analytics (BI phase 1) -->
|
<!-- Deep analytics (BI phase 1) -->
|
||||||
<div class="deep-grid">
|
<div class="deep-grid">
|
||||||
<UiCard class="chart-card" title="تبدیل مراحل کاریز">
|
<UiCard class="chart-card" title="تبدیل مراحل مسیر فروش">
|
||||||
<p class="deep-hint">
|
<p class="deep-hint">
|
||||||
سهم هر مرحله از معاملات باز و نرخ عبور نسبت به مرحله قبل. برای دیدن پروندهها روی مرحله کلیک کنید.
|
سهم هر مرحله از معاملات باز و نرخ عبور نسبت به مرحله قبل. برای دیدن پروندهها روی مرحله کلیک کنید.
|
||||||
</p>
|
</p>
|
||||||
@@ -1435,16 +1435,16 @@ const activityMax = computed(() =>
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="funnel-row-meta">
|
<div class="funnel-row-meta">
|
||||||
<small>سهم کاریز: {{ toFaDigits(s.shareOfPipelinePercent) }}٪</small>
|
<small>سهم از مسیر: {{ toFaDigits(s.shareOfPipelinePercent) }}٪</small>
|
||||||
<small v-if="s.conversionFromPrevPercent != null">
|
<small v-if="s.conversionFromPrevPercent != null">
|
||||||
تبدیل از قبل: {{ toFaDigits(s.conversionFromPrevPercent) }}٪
|
تبدیل از قبل: {{ toFaDigits(s.conversionFromPrevPercent) }}٪
|
||||||
</small>
|
</small>
|
||||||
<small v-else>شروع کاریز</small>
|
<small v-else>شروع مسیر</small>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p v-else class="empty-msg">معامله بازی در کاریز نیست.</p>
|
<p v-else class="empty-msg">معامله بازی در مسیر فروش نیست.</p>
|
||||||
</UiCard>
|
</UiCard>
|
||||||
|
|
||||||
<UiCard class="chart-card" title="مقایسه با دوره قبل">
|
<UiCard class="chart-card" title="مقایسه با دوره قبل">
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ const forecastChartOption = computed<UiChartOption>(() => {
|
|||||||
grid: { left: '3%', right: '4%', bottom: '8%', top: '8%', containLabel: true },
|
grid: { left: '3%', right: '4%', bottom: '8%', top: '8%', containLabel: true },
|
||||||
xAxis: {
|
xAxis: {
|
||||||
type: 'category',
|
type: 'category',
|
||||||
data: ['هدف دوره', 'تحققیافته', 'کاریز باز', 'پیشبینی'],
|
data: ['هدف دوره', 'تحققیافته', 'معاملات باز', 'پیشبینی'],
|
||||||
axisLine: { lineStyle: { color: '#cbd5e1' } },
|
axisLine: { lineStyle: { color: '#cbd5e1' } },
|
||||||
axisLabel: { color: '#64748b', fontFamily: 'IRANSans' },
|
axisLabel: { color: '#64748b', fontFamily: 'IRANSans' },
|
||||||
},
|
},
|
||||||
@@ -721,7 +721,7 @@ onMounted(() => {
|
|||||||
<h3>خلاصه پیشبینی</h3>
|
<h3>خلاصه پیشبینی</h3>
|
||||||
<div class="sum-row"><span>هدف دوره</span><strong>{{ formatMoney(forecast?.targetAmount || 0) }}</strong></div>
|
<div class="sum-row"><span>هدف دوره</span><strong>{{ formatMoney(forecast?.targetAmount || 0) }}</strong></div>
|
||||||
<div class="sum-row"><span>تحقق (برنده)</span><strong>{{ formatMoney(forecast?.wonAmount || 0) }}</strong></div>
|
<div class="sum-row"><span>تحقق (برنده)</span><strong>{{ formatMoney(forecast?.wonAmount || 0) }}</strong></div>
|
||||||
<div class="sum-row"><span>کاریز باز</span><strong>{{ formatMoney(forecast?.openPipelineAmount || 0) }}</strong></div>
|
<div class="sum-row"><span>معاملات باز</span><strong>{{ formatMoney(forecast?.openPipelineAmount || 0) }}</strong></div>
|
||||||
<div class="sum-row payable"><span>پیشبینی درآمد</span><strong>{{ formatMoney(forecast?.forecastAmount || 0) }}</strong></div>
|
<div class="sum-row payable"><span>پیشبینی درآمد</span><strong>{{ formatMoney(forecast?.forecastAmount || 0) }}</strong></div>
|
||||||
<div class="sum-row"><span>مشتریان جدید</span><strong>{{ toFaDigits(forecast?.newCustomersCount || 0) }}</strong></div>
|
<div class="sum-row"><span>مشتریان جدید</span><strong>{{ toFaDigits(forecast?.newCustomersCount || 0) }}</strong></div>
|
||||||
<div class="sum-row"><span>معاملات جدید</span><strong>{{ toFaDigits(forecast?.newDealsCount || 0) }}</strong></div>
|
<div class="sum-row"><span>معاملات جدید</span><strong>{{ toFaDigits(forecast?.newDealsCount || 0) }}</strong></div>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
CRM فروش و پشتیبانی برای تیمهای ایرانی — از سرنخ تا فاکتور، در یک پنل.
|
CRM فروش و پشتیبانی برای تیمهای ایرانی — از سرنخ تا فاکتور، در یک پنل.
|
||||||
|
|
||||||
**متن کوتاه (۲–۳ خط):**
|
**متن کوتاه (۲–۳ خط):**
|
||||||
مُنتَکت دفتر کار دیجیتال فروش شماست: مشتری و لید، کاریز معامله، کار روزانه، گفتگو و پشتیبانی، گزارش و اتوماسیون — با تاریخ شمسی، پیامک و رابط موبایل.
|
مُنتَکت دفتر کار دیجیتال فروش شماست: مشتری و لید، مسیر فروش، کار روزانه، گفتگو و پشتیبانی، گزارش و اتوماسیون — با تاریخ شمسی، پیامک و رابط موبایل.
|
||||||
|
|
||||||
**دکمهها:**
|
**دکمهها:**
|
||||||
| دکمه | مقصد |
|
| دکمه | مقصد |
|
||||||
@@ -40,11 +40,11 @@ CRM فروش و پشتیبانی برای تیمهای ایرانی — از
|
|||||||
مُنتَکت یک CRM **فروشمحور و پشتیبانیمحور** برای کسبوکارهای ایرانی است. حلقهٔ اصلی محصول این است:
|
مُنتَکت یک CRM **فروشمحور و پشتیبانیمحور** برای کسبوکارهای ایرانی است. حلقهٔ اصلی محصول این است:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
سرنخ → شخص / شرکت → معامله در کاریز → فعالیت و یادداشت هوشمند → فاکتور و پیشفاکتور → پس از فروش (تیکت، پرتال، وفاداری)
|
سرنخ → شخص / شرکت → معامله در مسیر فروش → فعالیت و یادداشت هوشمند → فاکتور و پیشفاکتور → پس از فروش (تیکت، پرتال، وفاداری)
|
||||||
```
|
```
|
||||||
|
|
||||||
**برای چه کسبوکارهایی مناسب است؟**
|
**برای چه کسبوکارهایی مناسب است؟**
|
||||||
فروش B2B/B2C، تیمهای چندنفره، و کسبوکارهایی که به **پیگیری منظم مشتری**، **کاریز فروش** و **پشتیبانی بعد از فروش** نیاز دارند — از جمله حوزه **طلا و جواهر** با اتصال **تهحساب**.
|
فروش B2B/B2C، تیمهای چندنفره، و کسبوکارهایی که به **پیگیری منظم مشتری**، **مسیر فروش** و **پشتیبانی بعد از فروش** نیاز دارند — از جمله حوزه **طلا و جواهر** با اتصال **تهحساب**.
|
||||||
|
|
||||||
**تمایز کلی (یک جمله):**
|
**تمایز کلی (یک جمله):**
|
||||||
هویت بصری مستقل، تمرکز روی ثبت سریع اطلاعات (Smart Notes) و دستیار هوشمند روی پرونده مشتری — نه فقط جدول و فرم.
|
هویت بصری مستقل، تمرکز روی ثبت سریع اطلاعات (Smart Notes) و دستیار هوشمند روی پرونده مشتری — نه فقط جدول و فرم.
|
||||||
@@ -58,9 +58,9 @@ CRM فروش و پشتیبانی برای تیمهای ایرانی — از
|
|||||||
|
|
||||||
| # | قابلیت | توضیح یکخطی برای لندینگ |
|
| # | قابلیت | توضیح یکخطی برای لندینگ |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| 1 | **کاریز فروش (Kanban)** | معاملات را بین مراحل بکشید؛ چند قیف فروش برای یک سازمان. |
|
| 1 | **مسیر فروش (Kanban)** | معاملات را بین مراحل بکشید؛ چند قیف فروش برای یک سازمان. |
|
||||||
| 2 | **اشخاص و شرکتها** | دفترچه مشتری با جستجو، ضدتکراری، اکسل و فیلد سفارشی. |
|
| 2 | **اشخاص و شرکتها** | دفترچه مشتری با جستجو، ضدتکراری، اکسل و فیلد سفارشی. |
|
||||||
| 3 | **مدیریت لیدها** | لید جدا از مشتری؛ ایمپورت اکسل، تخصیص، کاریز لید، تبدیل به مشتری. |
|
| 3 | **مدیریت لیدها** | لید جدا از مشتری؛ ایمپورت اکسل، تخصیص، مسیر لید، تبدیل به مشتری. |
|
||||||
| 4 | **فرمساز سرنخ** | فرم عمومی با لینک، iframe و QR برای جذب سرنخ. |
|
| 4 | **فرمساز سرنخ** | فرم عمومی با لینک، iframe و QR برای جذب سرنخ. |
|
||||||
| 5 | **Smart Notes و Montact Memory** | یادداشت سریع روی پرونده + خلاصه پایدار مشتری با منبع. |
|
| 5 | **Smart Notes و Montact Memory** | یادداشت سریع روی پرونده + خلاصه پایدار مشتری با منبع. |
|
||||||
| 6 | **Ask Montact** | پرسش به زبان طبیعی از روی یادداشتها و زمینه پرونده. |
|
| 6 | **Ask Montact** | پرسش به زبان طبیعی از روی یادداشتها و زمینه پرونده. |
|
||||||
|
|||||||
@@ -14,13 +14,13 @@
|
|||||||
|---|---|
|
|---|---|
|
||||||
| `images/01-dashboard-desktop.png` | داشبورد دسکتاپ |
|
| `images/01-dashboard-desktop.png` | داشبورد دسکتاپ |
|
||||||
| `images/02-contacts-people.png` | اشخاص |
|
| `images/02-contacts-people.png` | اشخاص |
|
||||||
| `images/03-pipeline-desktop.png` | کاریز فروش |
|
| `images/03-pipeline-desktop.png` | مسیر فروش |
|
||||||
| `images/04-conversations-desktop.png` | گفتگو |
|
| `images/04-conversations-desktop.png` | گفتگو |
|
||||||
| `images/05-reports-desktop.png` | گزارشها |
|
| `images/05-reports-desktop.png` | گزارشها |
|
||||||
| `images/06-dashboard-mobile.png` | داشبورد موبایلوار |
|
| `images/06-dashboard-mobile.png` | داشبورد موبایلوار |
|
||||||
| `images/07-contacts-companies.png` | شرکتها |
|
| `images/07-contacts-companies.png` | شرکتها |
|
||||||
| `images/08-leads-list.png` | فهرست لیدها |
|
| `images/08-leads-list.png` | فهرست لیدها |
|
||||||
| `images/09-leads-board.png` | کاریز لیدها |
|
| `images/09-leads-board.png` | مسیر لیدها |
|
||||||
| `images/10-activities.png` | میز کار |
|
| `images/10-activities.png` | میز کار |
|
||||||
| `images/11-calendar.png` | تقویم |
|
| `images/11-calendar.png` | تقویم |
|
||||||
| `images/12-notes.png` | یادداشتها |
|
| `images/12-notes.png` | یادداشتها |
|
||||||
@@ -31,4 +31,4 @@
|
|||||||
| `images/17-message-automations.png` | اتوماسیون پیامک |
|
| `images/17-message-automations.png` | اتوماسیون پیامک |
|
||||||
| `images/18-settings-team.png` | تنظیمات تیم |
|
| `images/18-settings-team.png` | تنظیمات تیم |
|
||||||
| `images/19-products.png` | محصولات |
|
| `images/19-products.png` | محصولات |
|
||||||
| `images/20-projects.png` | کاریز پروژه |
|
| `images/20-projects.png` | تابلوی پروژه |
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
منتکت یک CRM فروش و پشتیبانی برای کسبوکارهای ایرانی است با این حلقه اصلی:
|
منتکت یک CRM فروش و پشتیبانی برای کسبوکارهای ایرانی است با این حلقه اصلی:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
سرنخ → شخص / شرکت → معامله در کاریز → فعالیت / Smart Notes → فروش مالی سبک → پسازفروش
|
سرنخ → شخص / شرکت → معامله در مسیر فروش → فعالیت / Smart Notes → فروش مالی سبک → پسازفروش
|
||||||
```
|
```
|
||||||
|
|
||||||
الهام اولیه از محصولات ایرانی مثل دیدار بوده، ولی هویت بصری و تمایز محصول مستقل است:
|
الهام اولیه از محصولات ایرانی مثل دیدار بوده، ولی هویت بصری و تمایز محصول مستقل است:
|
||||||
@@ -49,7 +49,7 @@
|
|||||||
|
|
||||||
| مایلاستون | وضعیت | محتوا |
|
| مایلاستون | وضعیت | محتوا |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| **۱-الف** هسته فروش | انجام شده | مخاطب، کاریز، فعالیت، تقویم، اکسل، نقش، چندارزی، UI |
|
| **۱-الف** هسته فروش | انجام شده | مخاطب، مسیر فروش، فعالیت، تقویم، اکسل، نقش، چندارزی، UI |
|
||||||
| **۱-ب** Smart Notes / AI | انجام شده | Composer، Memory، Ask، Voice؛ شخصی/تیمی + تاریخچه؛ خلاصه خودکار تماس |
|
| **۱-ب** Smart Notes / AI | انجام شده | Composer، Memory، Ask، Voice؛ شخصی/تیمی + تاریخچه؛ خلاصه خودکار تماس |
|
||||||
| **۱-ج** سرنخ و مالی | انجام شده | فرمساز، پیشفاکتور، فاکتور/اقساط، هدف فروش |
|
| **۱-ج** سرنخ و مالی | انجام شده | فرمساز، پیشفاکتور، فاکتور/اقساط، هدف فروش |
|
||||||
| **۱-د** پسازفروش | انجام شده | تیکت، پرتال OTP، پروژه، باشگاه، تهحساب |
|
| **۱-د** پسازفروش | انجام شده | تیکت، پرتال OTP، پروژه، باشگاه، تهحساب |
|
||||||
@@ -81,7 +81,7 @@
|
|||||||
| احراز هویت (رمز + OTP موبایل) | آماده |
|
| احراز هویت (رمز + OTP موبایل) | آماده |
|
||||||
| خانه / داشبورد | آماده |
|
| خانه / داشبورد | آماده |
|
||||||
| اشخاص و شرکتها + پروفایل | آماده |
|
| اشخاص و شرکتها + پروفایل | آماده |
|
||||||
| کاریز فروش و معامله | آماده |
|
| مسیر فروش و معامله | آماده |
|
||||||
| فعالیت، تقویم، یادآور SMS/اپ | آماده |
|
| فعالیت، تقویم، یادآور SMS/اپ | آماده |
|
||||||
| یادداشت هوشمند / Memory / Ask | آماده |
|
| یادداشت هوشمند / Memory / Ask | آماده |
|
||||||
| پیشفاکتور و فاکتور | آماده |
|
| پیشفاکتور و فاکتور | آماده |
|
||||||
|
|||||||
+19
-19
@@ -140,7 +140,7 @@
|
|||||||
- **منابع مشتریان:** مشتریها از کجا آمدهاند
|
- **منابع مشتریان:** مشتریها از کجا آمدهاند
|
||||||
- **دستیار هوشمند:** پیشنهاد سؤال و دستورهای سریع (حتی با میکروفون در صورت فعال بودن)
|
- **دستیار هوشمند:** پیشنهاد سؤال و دستورهای سریع (حتی با میکروفون در صورت فعال بودن)
|
||||||
- **فعالیتهای اخیر**
|
- **فعالیتهای اخیر**
|
||||||
- **نمای کوچک کاریز فروش**
|
- **نمای کوچک مسیر فروش**
|
||||||
- **برترین مشتریان**
|
- **برترین مشتریان**
|
||||||
|
|
||||||
### دسکتاپ در برابر موبایل
|
### دسکتاپ در برابر موبایل
|
||||||
@@ -199,13 +199,13 @@
|
|||||||
- تخصیص به همکار
|
- تخصیص به همکار
|
||||||
- ورود از اکسل (اگر دسترسی دارید)
|
- ورود از اکسل (اگر دسترسی دارید)
|
||||||
|
|
||||||
### کاریز لیدها
|
### مسیر لیدها
|
||||||

|

|
||||||
|
|
||||||
نمای ستونبهستون (کانبان). کارت را بین مراحل بکشید تا وضعیت عوض شود.
|
نمای ستونبهستون (کانبان). کارت را بین مراحل بکشید تا وضعیت عوض شود.
|
||||||
|
|
||||||
### مراحل و وضعیتها (معمولاً فقط مدیر)
|
### مراحل و وضعیتها (معمولاً فقط مدیر)
|
||||||
تعریف ستونهای کاریز لید.
|
تعریف ستونهای مسیر لید.
|
||||||
|
|
||||||
### فرمساز سرنخ (معمولاً فقط مدیر)
|
### فرمساز سرنخ (معمولاً فقط مدیر)
|
||||||
- لینک عمومی برای جذب سرنخ
|
- لینک عمومی برای جذب سرنخ
|
||||||
@@ -218,10 +218,10 @@
|
|||||||
|
|
||||||
مسیر: منو → **فروش**
|
مسیر: منو → **فروش**
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
### کاریز فروش
|
### مسیر فروش
|
||||||
- نمای **کاریز** (ستونها) یا **لیست**
|
- نمای **ستونی** یا **لیست**
|
||||||
- هر ستون یک مرحله است (مثلاً سرنخ، تماس اول، پیشنهاد، …)
|
- هر ستون یک مرحله است (مثلاً سرنخ، تماس اول، پیشنهاد، …)
|
||||||
- کارت معامله را بکشید تا مرحله عوض شود
|
- کارت معامله را بکشید تا مرحله عوض شود
|
||||||
- روی کارت بزنید تا جزئیات باز شود: مبلغ، مسئول، محصولات، یادداشت، …
|
- روی کارت بزنید تا جزئیات باز شود: مبلغ، مسئول، محصولات، یادداشت، …
|
||||||
@@ -372,7 +372,7 @@
|
|||||||
- بازه زمانی: امروز / هفته / ماه / سهماهه / سال یا تاریخ دلخواه
|
- بازه زمانی: امروز / هفته / ماه / سهماهه / سال یا تاریخ دلخواه
|
||||||
- کارتهایی مثل: مشتریان جدید، تعداد فاکتور، مبلغ فروش، میانگینها
|
- کارتهایی مثل: مشتریان جدید، تعداد فاکتور، مبلغ فروش، میانگینها
|
||||||
- مقایسه با دوره قبل
|
- مقایسه با دوره قبل
|
||||||
- قیف تبدیل مراحل کاریز
|
- قیف تبدیل مراحل مسیر فروش
|
||||||
- نمودارها و جداول فروش، منابع، فعالیت، تیم، تیکت
|
- نمودارها و جداول فروش، منابع، فعالیت، تیم، تیکت
|
||||||
- خروجی اکسل/CSV
|
- خروجی اکسل/CSV
|
||||||
- ذخیره نما و کپی لینک اشتراک (اگر فعال باشد)
|
- ذخیره نما و کپی لینک اشتراک (اگر فعال باشد)
|
||||||
@@ -419,11 +419,11 @@
|
|||||||
|
|
||||||
مسیر: منو → **ابزارها**
|
مسیر: منو → **ابزارها**
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
| بخش | کار ساده |
|
| بخش | کار ساده |
|
||||||
|---|---|
|
|---|---|
|
||||||
| کاریز پروژه | کارهای داخلی تیم بعد از فروش (ستونها و کارتها) |
|
| تابلوی پروژه | کارهای داخلی تیم بعد از فروش (ستونها و کارتها) |
|
||||||
| انبار | موجودی کالا و جابهجایی داخلی |
|
| انبار | موجودی کالا و جابهجایی داخلی |
|
||||||
| چکها | چک دریافتی و پرداختی + یادآوری |
|
| چکها | چک دریافتی و پرداختی + یادآوری |
|
||||||
| رزرو و نوبتدهی | خدمات، زمان آزاد، ثبت نوبت مشتری |
|
| رزرو و نوبتدهی | خدمات، زمان آزاد، ثبت نوبت مشتری |
|
||||||
@@ -463,7 +463,7 @@
|
|||||||
1. منو را با آیکون همبرگر باز کنید.
|
1. منو را با آیکون همبرگر باز کنید.
|
||||||
2. لیستها کارتمانند هستند؛ برای دیدن جزئیات روی کارت بزنید.
|
2. لیستها کارتمانند هستند؛ برای دیدن جزئیات روی کارت بزنید.
|
||||||
3. در فرمها دکمهٔ ذخیره اغلب **بالا** و با آیکون تیک است.
|
3. در فرمها دکمهٔ ذخیره اغلب **بالا** و با آیکون تیک است.
|
||||||
4. کاریز فروش/لید را افقی ورق بزنید.
|
4. مسیر فروش/لید را افقی ورق بزنید.
|
||||||
5. در گفتگو: لمس طولانی روی پیام = منوی کارها.
|
5. در گفتگو: لمس طولانی روی پیام = منوی کارها.
|
||||||
6. برای گزارشهای شلوغ و اکسل، دسکتاپ راحتتر است.
|
6. برای گزارشهای شلوغ و اکسل، دسکتاپ راحتتر است.
|
||||||
7. ورود از مخاطبین گوشی در صفحه اشخاص در دسترس است.
|
7. ورود از مخاطبین گوشی در صفحه اشخاص در دسترس است.
|
||||||
@@ -474,11 +474,11 @@
|
|||||||
|
|
||||||
### کارشناس فروش
|
### کارشناس فروش
|
||||||
1. لید جدید (دستی یا از فرم سایت)
|
1. لید جدید (دستی یا از فرم سایت)
|
||||||
2. تبدیل/ساخت معامله روی کاریز
|
2. تبدیل/ساخت معامله روی مسیر فروش
|
||||||
3. ثبت تماس و یادداشت
|
3. ثبت تماس و یادداشت
|
||||||
4. پیشفاکتور → فاکتور
|
4. پیشفاکتور → فاکتور
|
||||||
5. بردن معامله به مرحله برنده
|
5. بردن معامله به مرحله برنده
|
||||||
6. در صورت نیاز کارت در کاریز پروژه
|
6. در صورت نیاز کارت در تابلوی پروژه
|
||||||
|
|
||||||
### پشتیبانی
|
### پشتیبانی
|
||||||
1. تیکت جدید یا پیام از پرتال
|
1. تیکت جدید یا پیام از پرتال
|
||||||
@@ -508,7 +508,7 @@
|
|||||||
|
|
||||||
## جمعبندی یکخطی
|
## جمعبندی یکخطی
|
||||||
|
|
||||||
مُنتَکت دفتر کار دیجیتال تیم شماست: مشتری و لید را نگه میدارد، فروش را روی کاریز جلو میبرد، کار و گفتگو و پشتیبانی را یکجا میکند، و با گزارش و اتوماسیون به مدیر نشان میدهد واقعاً چه خبر است — هم روی کامپیوتر، هم روی گوشی.
|
مُنتَکت دفتر کار دیجیتال تیم شماست: مشتری و لید را نگه میدارد، فروش را روی مسیر فروش جلو میبرد، کار و گفتگو و پشتیبانی را یکجا میکند، و با گزارش و اتوماسیون به مدیر نشان میدهد واقعاً چه خبر است — هم روی کامپیوتر، هم روی گوشی.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -517,8 +517,8 @@
|
|||||||
```
|
```
|
||||||
داشبورد
|
داشبورد
|
||||||
مشتریان → اشخاص / شرکتها
|
مشتریان → اشخاص / شرکتها
|
||||||
لیدها → فهرست / کاریز / مراحل / فرمساز
|
لیدها → فهرست / مسیر لیدها / مراحل / فرمساز
|
||||||
فروش → کاریز / محصولات / فاکتور / پیشفاکتور / پورسانت / هدف
|
فروش → مسیر فروش / محصولات / فاکتور / پیشفاکتور / پورسانت / هدف
|
||||||
کارها → میز کار / تقویم
|
کارها → میز کار / تقویم
|
||||||
گفتگو
|
گفتگو
|
||||||
یادداشتها
|
یادداشتها
|
||||||
@@ -536,13 +536,13 @@
|
|||||||
|---|---|
|
|---|---|
|
||||||
| `01-dashboard-desktop.png` | داشبورد دسکتاپ |
|
| `01-dashboard-desktop.png` | داشبورد دسکتاپ |
|
||||||
| `02-contacts-people.png` | اشخاص |
|
| `02-contacts-people.png` | اشخاص |
|
||||||
| `03-pipeline-desktop.png` | کاریز فروش |
|
| `03-pipeline-desktop.png` | مسیر فروش |
|
||||||
| `04-conversations-desktop.png` | گفتگو |
|
| `04-conversations-desktop.png` | گفتگو |
|
||||||
| `05-reports-desktop.png` | گزارشها |
|
| `05-reports-desktop.png` | گزارشها |
|
||||||
| `06-dashboard-mobile.png` | داشبورد موبایلوار |
|
| `06-dashboard-mobile.png` | داشبورد موبایلوار |
|
||||||
| `07-contacts-companies.png` | شرکتها |
|
| `07-contacts-companies.png` | شرکتها |
|
||||||
| `08-leads-list.png` | فهرست لیدها |
|
| `08-leads-list.png` | فهرست لیدها |
|
||||||
| `09-leads-board.png` | کاریز لیدها |
|
| `09-leads-board.png` | مسیر لیدها |
|
||||||
| `10-activities.png` | میز کار و فعالیتها |
|
| `10-activities.png` | میز کار و فعالیتها |
|
||||||
| `11-calendar.png` | تقویم فعالیتها |
|
| `11-calendar.png` | تقویم فعالیتها |
|
||||||
| `12-notes.png` | یادداشتها |
|
| `12-notes.png` | یادداشتها |
|
||||||
@@ -553,4 +553,4 @@
|
|||||||
| `17-message-automations.png` | اتوماسیون پیامک |
|
| `17-message-automations.png` | اتوماسیون پیامک |
|
||||||
| `18-settings-team.png` | تنظیمات تیم و کاربران |
|
| `18-settings-team.png` | تنظیمات تیم و کاربران |
|
||||||
| `19-products.png` | محصولات |
|
| `19-products.png` | محصولات |
|
||||||
| `20-projects.png` | کاریز پروژه |
|
| `20-projects.png` | تابلوی پروژه |
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
## خانه و پروفایل
|
## خانه و پروفایل
|
||||||
|
|
||||||
### داشبورد خانه امروز
|
### داشبورد خانه امروز
|
||||||
خلاصه فروش، فعالیت، کاریز، میانبرها و دستیار Ask Montact در یک صفحه.
|
خلاصه فروش، فعالیت، مسیر فروش، میانبرها و دستیار Ask Montact در یک صفحه.
|
||||||
|
|
||||||
### پروفایل کاربر
|
### پروفایل کاربر
|
||||||
از کارت پایین سایدبار: وضعیت کارها و میانبرهای شخصی.
|
از کارت پایین سایدبار: وضعیت کارها و میانبرهای شخصی.
|
||||||
@@ -62,12 +62,12 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## فروش و کاریز
|
## فروش و مسیر فروش
|
||||||
|
|
||||||
### کاریز فروش کانبان
|
### مسیر فروش (نمای ستونی)
|
||||||
تخته ستونی معاملات با کشیدن کارت بین مراحل.
|
تخته ستونی معاملات با کشیدن کارت بین مراحل.
|
||||||
|
|
||||||
### چند کاریز
|
### چند مسیر فروش
|
||||||
سازمان میتواند بیش از یک قیف فروش داشته باشد.
|
سازمان میتواند بیش از یک قیف فروش داشته باشد.
|
||||||
|
|
||||||
### پرونده معامله
|
### پرونده معامله
|
||||||
@@ -152,7 +152,7 @@ AI پیشنهاد Next Action میدهد؛ اعمال فقط با تأیید
|
|||||||
## سرنخ و مالی سبک
|
## سرنخ و مالی سبک
|
||||||
|
|
||||||
### مدیریت لیدها
|
### مدیریت لیدها
|
||||||
دیتابیس جدا از مشتریان برای مخاطبین بالقوه: ایمپورت اکسل، تخصیص به کارشناس، کاریز لید، ثبت تماس/پیگیری، و تبدیل به مشتری.
|
دیتابیس جدا از مشتریان برای مخاطبین بالقوه: ایمپورت اکسل، تخصیص به کارشناس، مسیر لید، ثبت تماس/پیگیری، و تبدیل به مشتری.
|
||||||
|
|
||||||
### فرمساز سرنخ
|
### فرمساز سرنخ
|
||||||
فرم وب عمومی با لینک، iframe و QR؛ ساخت شخص و معامله.
|
فرم وب عمومی با لینک، iframe و QR؛ ساخت شخص و معامله.
|
||||||
@@ -198,7 +198,7 @@ AI پیشنهاد Next Action میدهد؛ اعمال فقط با تأیید
|
|||||||
|
|
||||||
## پروژه، وفاداری، اتوماسیون
|
## پروژه، وفاداری، اتوماسیون
|
||||||
|
|
||||||
### کاریز پروژه
|
### تابلوی پروژه
|
||||||
تخته کارهای داخلی (صف / انجام / بازبینی / تمام) جدا از فروش.
|
تخته کارهای داخلی (صف / انجام / بازبینی / تمام) جدا از فروش.
|
||||||
|
|
||||||
### باشگاه مشتریان
|
### باشگاه مشتریان
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ export const ORG_MODULE_KEYS: OrgModuleKey[] = [
|
|||||||
|
|
||||||
export const ORG_MODULE_LABELS: Record<OrgModuleKey, string> = {
|
export const ORG_MODULE_LABELS: Record<OrgModuleKey, string> = {
|
||||||
customers: "مشتریان",
|
customers: "مشتریان",
|
||||||
pipeline: "کاریز فروش",
|
pipeline: "مسیر فروش",
|
||||||
products: "محصولات",
|
products: "محصولات",
|
||||||
invoices: "فاکتورها",
|
invoices: "فاکتورها",
|
||||||
quotes: "پیشفاکتورها",
|
quotes: "پیشفاکتورها",
|
||||||
@@ -192,7 +192,7 @@ export const ORG_MODULE_LABELS: Record<OrgModuleKey, string> = {
|
|||||||
message_automations: "اتوماسیون پیامک",
|
message_automations: "اتوماسیون پیامک",
|
||||||
lead_forms: "فرمساز سرنخ",
|
lead_forms: "فرمساز سرنخ",
|
||||||
leads: "مدیریت لیدها",
|
leads: "مدیریت لیدها",
|
||||||
project_boards: "کاریز پروژه",
|
project_boards: "تابلوی پروژه",
|
||||||
inventory: "انبار",
|
inventory: "انبار",
|
||||||
cheques: "چکها",
|
cheques: "چکها",
|
||||||
attachments: "پیوستها",
|
attachments: "پیوستها",
|
||||||
@@ -1056,8 +1056,8 @@ export const DEAL_EXCEL_COLUMNS: Array<{ header: string; key: string; width?: nu
|
|||||||
{ header: "معرف معامله", key: "referrer", width: 16 },
|
{ header: "معرف معامله", key: "referrer", width: 16 },
|
||||||
{ header: "شیوه آشنایی دلخواه", key: "sourceDetail", width: 16 },
|
{ header: "شیوه آشنایی دلخواه", key: "sourceDetail", width: 16 },
|
||||||
{ header: "برچسب", key: "tags", width: 16 },
|
{ header: "برچسب", key: "tags", width: 16 },
|
||||||
{ header: "کاریز معامله", key: "pipelineName", width: 20 },
|
{ header: "مسیر فروش معامله", key: "pipelineName", width: 20 },
|
||||||
{ header: "مرحله کاریز معامله", key: "stageName", width: 20 },
|
{ header: "مرحله مسیر فروش معامله", key: "stageName", width: 20 },
|
||||||
{ header: "نام شخص معامله", key: "personFirstName", width: 16 },
|
{ header: "نام شخص معامله", key: "personFirstName", width: 16 },
|
||||||
{ header: "نام خانوادگی شخص معامله", key: "personName", width: 22 },
|
{ header: "نام خانوادگی شخص معامله", key: "personName", width: 22 },
|
||||||
{ header: "کد دیدار شخص معامله", key: "personCode", width: 14 },
|
{ header: "کد دیدار شخص معامله", key: "personCode", width: 14 },
|
||||||
@@ -1104,7 +1104,12 @@ export const DEAL_EXCEL_ALIASES: Record<string, string> = {
|
|||||||
شرکت: "companyName",
|
شرکت: "companyName",
|
||||||
منبعمعامله: "source",
|
منبعمعامله: "source",
|
||||||
منبع: "source",
|
منبع: "source",
|
||||||
|
مسیرفروش: "pipelineName",
|
||||||
|
مسیر: "pipelineName",
|
||||||
|
// سرستونهای قدیمی (قبل از تغییر نام کاریز → مسیر فروش)
|
||||||
کاریز: "pipelineName",
|
کاریز: "pipelineName",
|
||||||
|
کاریزمعامله: "pipelineName",
|
||||||
|
مرحلهکاریزمعامله: "stageName",
|
||||||
مرحله: "stageName",
|
مرحله: "stageName",
|
||||||
};
|
};
|
||||||
/** فیلتر ذخیرهشدهٔ لیست اشخاص */
|
/** فیلتر ذخیرهشدهٔ لیست اشخاص */
|
||||||
@@ -1115,7 +1120,7 @@ export interface PeopleViewFilters {
|
|||||||
page?: number;
|
page?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** فیلتر ذخیرهشدهٔ کاریز / معاملات */
|
/** فیلتر ذخیرهشدهٔ مسیر فروش / معاملات */
|
||||||
export interface DealsViewFilters {
|
export interface DealsViewFilters {
|
||||||
q?: string;
|
q?: string;
|
||||||
amountMin?: string;
|
amountMin?: string;
|
||||||
@@ -2251,7 +2256,7 @@ export interface SalesForecastDto {
|
|||||||
wonAmount: number;
|
wonAmount: number;
|
||||||
/** معاملات باز فعلی */
|
/** معاملات باز فعلی */
|
||||||
openPipelineAmount: number;
|
openPipelineAmount: number;
|
||||||
/** پیشبینی: تحقق + کاریز باز × میانگین احتمال */
|
/** پیشبینی: تحقق + معاملات باز × میانگین احتمال */
|
||||||
forecastAmount: number;
|
forecastAmount: number;
|
||||||
progressPercent: number | null;
|
progressPercent: number | null;
|
||||||
openDealsCount: number;
|
openDealsCount: number;
|
||||||
@@ -2501,9 +2506,9 @@ export interface ReportsFunnelStageDto {
|
|||||||
pipelineName: string;
|
pipelineName: string;
|
||||||
count: number;
|
count: number;
|
||||||
amount: number;
|
amount: number;
|
||||||
/** درصد تبدیل نسبت به مرحله قبل همان کاریز؛ null برای اولین مرحله */
|
/** درصد تبدیل نسبت به مرحله قبل همان مسیر فروش؛ null برای اولین مرحله */
|
||||||
conversionFromPrevPercent: number | null;
|
conversionFromPrevPercent: number | null;
|
||||||
/** سهم از کل معاملات باز همان کاریز */
|
/** سهم از کل معاملات باز همان مسیر فروش */
|
||||||
shareOfPipelinePercent: number;
|
shareOfPipelinePercent: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2658,7 +2663,7 @@ export interface HomeDashboardDto {
|
|||||||
topCustomers: HomeDashboardTopCustomerDto[];
|
topCustomers: HomeDashboardTopCustomerDto[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** برد پروژه / کاریز کارت */
|
/** تابلوی پروژه / کارت */
|
||||||
export interface ProjectBoardStageDto {
|
export interface ProjectBoardStageDto {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
@@ -3586,7 +3591,7 @@ export const REPORTS_BUILDER_DIMENSION_LABELS: Record<
|
|||||||
owner: "کاربر / مسئول",
|
owner: "کاربر / مسئول",
|
||||||
team: "تیم",
|
team: "تیم",
|
||||||
source: "منبع",
|
source: "منبع",
|
||||||
stage: "مرحله کاریز",
|
stage: "مرحله مسیر فروش",
|
||||||
month: "ماه",
|
month: "ماه",
|
||||||
status: "وضعیت معامله",
|
status: "وضعیت معامله",
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user