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

@@ -16,6 +16,10 @@ interface MonthBucket {
purchases: number
}
function isSaleInvoice(invoice: ReturnType<typeof useStore>['data']['invoices'][number]): boolean {
return invoice.kind === 'sale' && (invoice.documentType ?? 'invoice') === 'invoice' && invoice.status !== 'draft'
}
function monthlyBuckets(
invoices: ReturnType<typeof useStore>['data']['invoices'],
): MonthBucket[] {
@@ -33,10 +37,10 @@ function monthlyBuckets(
buckets.push({
label: formatter.format(date),
sales: inMonth
.filter((i) => i.kind === 'sale')
.filter(isSaleInvoice)
.reduce((sum, i) => sum + invoiceTotals(i).net, 0),
purchases: inMonth
.filter((i) => i.kind === 'purchase')
.filter((i) => i.kind === 'purchase' && i.status !== 'draft')
.reduce((sum, i) => sum + invoiceTotals(i).net, 0),
})
}
@@ -53,16 +57,18 @@ export function Dashboard() {
.reduce((sum, b) => sum + b.balance, 0)
const sales = data.invoices
.filter((i) => i.kind === 'sale')
.filter(isSaleInvoice)
.reduce((sum, i) => sum + invoiceTotals(i).net, 0)
const purchases = data.invoices
.filter((i) => i.kind === 'purchase')
.filter((i) => i.kind === 'purchase' && i.status !== 'draft')
.reduce((sum, i) => sum + invoiceTotals(i).net, 0)
const income = incomeStatement(balances)
const sheet = balanceSheet(balances)
const lowStock = data.products.filter((p) => p.stock <= p.reorderLevel)
const unpaidSales = data.invoices.filter((i) => i.kind === 'sale' && i.status !== 'paid')
const unpaidSales = data.invoices.filter(
(i) => i.kind === 'sale' && (i.documentType ?? 'invoice') === 'invoice' && i.status === 'confirmed',
)
return { liquidity, sales, purchases, income, sheet, lowStock, unpaidSales }
}, [data])
@@ -88,7 +94,7 @@ export function Dashboard() {
<StatCard
label="فروش کل"
value={formatMoney(metrics.sales)}
hint={`${toFa(data.invoices.filter((i) => i.kind === 'sale').length)} فاکتور فروش`}
hint={`${toFa(data.invoices.filter(isSaleInvoice).length)} فاکتور فروش`}
icon="🧾"
tone="green"
/>
@@ -190,8 +196,8 @@ export function Dashboard() {
<Card className="p-5">
<div className="mb-4 flex items-center justify-between">
<h2 className="text-lg font-bold text-slate-800">فاکتورهای فروش تسویهنشده</h2>
<Link to="/sales" className="text-sm font-medium text-brand-600 hover:underline">
مشاهده فروش
<Link to="/sales/review" className="text-sm font-medium text-brand-600 hover:underline">
مرور فروش
</Link>
</div>
{metrics.unpaidSales.length === 0 ? (