Expand sales, treasury, and parties modules with Jalali calendar and FunZone integrations

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Shayan Azadi
2026-07-03 03:15:52 +03:30
parent d7252f1d21
commit 4508be582a
55 changed files with 5083 additions and 799 deletions

View File

@@ -0,0 +1,110 @@
import { Link } from 'react-router-dom'
import { useMemo } from 'react'
import { useStore } from '../../store/AppStore'
import { Card, StatCard } from '../../components/ui'
import { formatMoney, toFa } from '../../utils/format'
import { salesNavItems } from './salesNavigation'
import { salesSummary } from './salesUtils'
const processSteps = [
{ step: 1, label: 'پیش‌فاکتور', desc: 'صدور پیشنهاد قیمت برای مشتری', to: '/sales/proforma', icon: '📋' },
{ step: 2, label: 'فاکتور فروش', desc: 'ثبت فروش قطعی و کاهش موجودی', to: '/sales/invoice', icon: '🧾' },
{ step: 3, label: 'دریافت', desc: 'تسویه از مشتری در ماژول دریافت و پرداخت', to: '/treasury', icon: '💰' },
{ step: 4, label: 'فاکتور برگشتی', desc: 'برداشت در انتظار مشتریان و برگشت کالا', to: '/sales/return', icon: '↩️' },
]
export function SalesProcess() {
const { data } = useStore()
const summary = useMemo(() => salesSummary(data), [data])
const quickLinks = salesNavItems.filter((item) => item.to !== '/sales')
return (
<div className="space-y-6">
<Card className="p-5">
<h2 className="mb-1 text-lg font-bold text-slate-800">فرایند فروش</h2>
<p className="mb-6 text-sm text-slate-500">
جریان استاندارد فروش مشابه سپیدار: از پیشفاکتور تا فاکتور، دریافت و برگشت.
</p>
<div className="grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4">
{processSteps.map((step, idx) => (
<div key={step.step} className="relative">
<Link
to={step.to}
className="flex flex-col rounded-xl border border-slate-200 bg-slate-50/50 p-4 transition hover:border-brand-200 hover:bg-brand-50/30"
>
<div className="mb-2 flex items-center gap-2">
<span className="flex h-7 w-7 items-center justify-center rounded-full bg-brand-100 text-xs font-bold text-brand-700">
{toFa(step.step)}
</span>
<span className="text-lg">{step.icon}</span>
</div>
<p className="font-semibold text-slate-800">{step.label}</p>
<p className="mt-1 text-xs text-slate-500">{step.desc}</p>
</Link>
{idx < processSteps.length - 1 && (
<span className="absolute -left-2 top-1/2 hidden -translate-y-1/2 text-slate-300 lg:block"></span>
)}
</div>
))}
</div>
</Card>
<div className="grid grid-cols-2 gap-4 lg:grid-cols-4">
<StatCard label="پیش‌فاکتور" value={toFa(summary.proformaCount)} hint={`${toFa(summary.openProformas)} باز`} />
<StatCard label="فاکتور فروش" value={toFa(summary.invoiceCount)} hint={formatMoney(summary.totalSales)} />
<StatCard label="فاکتور برگشتی" value={toFa(summary.returnCount)} hint={formatMoney(summary.totalReturns)} />
<StatCard label="فروش خالص" value={formatMoney(summary.netSales)} hint={`${toFa(summary.unpaidCount)} تسویه‌نشده`} />
</div>
<div className="grid grid-cols-1 gap-4 lg:grid-cols-2">
<Card className="p-5">
<h3 className="mb-3 font-bold text-slate-800">اتصال به سایر ماژولها</h3>
<ul className="space-y-2 text-sm text-slate-600">
<li className="flex items-start gap-2">
<span>📦</span>
<span>
<strong>انبارداری:</strong> فاکتور فروش قطعی موجودی را کاهش و فاکتور برگشتی آن را افزایش میدهد.
</span>
</li>
<li className="flex items-start gap-2">
<span>📑</span>
<span>
<strong>اسناد حسابداری:</strong> با تأیید فاکتور، سند درآمد/مطالبات بهصورت خودکار صادر میشود.
</span>
</li>
<li className="flex items-start gap-2">
<span>💰</span>
<span>
<strong>دریافت و پرداخت:</strong> دریافت از مشتری مانده حساب را کاهش میدهد.
</span>
</li>
<li className="flex items-start gap-2">
<span></span>
<span>
<strong>اعلامیه بدهکار/بستانکار:</strong> برای اصلاح مانده مشتری بدون فاکتور.
</span>
</li>
</ul>
</Card>
<Card className="p-5">
<h3 className="mb-3 font-bold text-slate-800">دسترسی سریع</h3>
<div className="grid grid-cols-2 gap-2">
{quickLinks.map((item) => (
<Link
key={item.to}
to={item.to}
className="flex items-center gap-2 rounded-lg border border-slate-200 px-3 py-2.5 text-sm font-medium text-slate-700 transition hover:border-brand-200 hover:bg-brand-50/40"
>
<span>{item.icon}</span>
<span>{item.label}</span>
</Link>
))}
</div>
</Card>
</div>
</div>
)
}