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

|
||||
### مسیر لیدها
|
||||

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

|
||||

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

|
||||

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