Expand sales, treasury, and parties modules with Jalali calendar and FunZone integrations
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -8,6 +8,7 @@ import {
|
||||
DataTable,
|
||||
Field,
|
||||
Input,
|
||||
JalaliDateInput,
|
||||
Modal,
|
||||
PageHeader,
|
||||
Select,
|
||||
@@ -15,7 +16,7 @@ import {
|
||||
} from '../components/ui'
|
||||
import type { Voucher, VoucherLine } from '../types'
|
||||
import { createId, nextNumber } from '../utils/id'
|
||||
import { formatDate, formatMoney, toFa } from '../utils/format'
|
||||
import { formatDate, formatMoney, todayISO, toFa } from '../utils/format'
|
||||
import { voucherBalance } from '../utils/accounting'
|
||||
|
||||
const newLine = (): VoucherLine => ({
|
||||
@@ -30,7 +31,7 @@ function createDraft(items: Voucher[]): Voucher {
|
||||
return {
|
||||
id: '',
|
||||
number: nextNumber(items),
|
||||
date: new Date().toISOString().slice(0, 10),
|
||||
date: todayISO(),
|
||||
description: '',
|
||||
status: 'draft',
|
||||
lines: [newLine(), newLine()],
|
||||
@@ -74,18 +75,45 @@ export function Vouchers() {
|
||||
}
|
||||
|
||||
const columns: Array<Column<Voucher>> = [
|
||||
{ key: 'number', header: 'شماره', render: (v) => <span className="font-mono">{toFa(v.number)}</span> },
|
||||
{ key: 'date', header: 'تاریخ', render: (v) => formatDate(v.date) },
|
||||
{ key: 'desc', header: 'شرح', render: (v) => <span className="text-slate-700">{v.description || '—'}</span> },
|
||||
{
|
||||
key: 'number',
|
||||
header: 'شماره',
|
||||
headerClassName: 'w-[4.5rem]',
|
||||
className: 'w-[4.5rem] whitespace-nowrap',
|
||||
render: (v) => <span className="font-mono">{toFa(v.number)}</span>,
|
||||
},
|
||||
{
|
||||
key: 'date',
|
||||
header: 'تاریخ',
|
||||
headerClassName: 'w-[6.5rem]',
|
||||
className: 'w-[6.5rem] whitespace-nowrap tabular-nums',
|
||||
render: (v) => formatDate(v.date),
|
||||
},
|
||||
{
|
||||
key: 'desc',
|
||||
header: 'شرح',
|
||||
truncate: true,
|
||||
className: 'min-w-0',
|
||||
render: (v) => (
|
||||
<span className="block truncate text-slate-700" title={v.description || undefined}>
|
||||
{v.description || '—'}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'amount',
|
||||
header: 'مبلغ',
|
||||
align: 'end',
|
||||
render: (v) => <span className="tabular-nums">{formatMoney(voucherBalance(v).debit)}</span>,
|
||||
headerClassName: 'w-[7.5rem]',
|
||||
className: 'w-[7.5rem] whitespace-nowrap tabular-nums',
|
||||
render: (v) => formatMoney(voucherBalance(v).debit),
|
||||
},
|
||||
{
|
||||
key: 'status',
|
||||
header: 'وضعیت',
|
||||
sticky: { left: '9rem' },
|
||||
headerClassName: 'w-[6.5rem]',
|
||||
className: 'w-[6.5rem] whitespace-nowrap',
|
||||
render: (v) =>
|
||||
v.status === 'posted' ? <Badge tone="green">ثبت قطعی</Badge> : <Badge tone="amber">پیشنویس</Badge>,
|
||||
},
|
||||
@@ -93,6 +121,9 @@ export function Vouchers() {
|
||||
key: 'actions',
|
||||
header: '',
|
||||
align: 'end',
|
||||
sticky: { left: '0' },
|
||||
headerClassName: 'w-[9rem]',
|
||||
className: 'w-[9rem] whitespace-nowrap',
|
||||
render: (v) => (
|
||||
<div className="flex justify-end gap-1">
|
||||
<Button size="sm" variant="ghost" onClick={() => setDraft({ ...v, lines: v.lines.map((l) => ({ ...l })) })}>
|
||||
@@ -171,7 +202,7 @@ export function Vouchers() {
|
||||
/>
|
||||
</Field>
|
||||
<Field label="تاریخ">
|
||||
<Input type="date" value={draft.date} onChange={(e) => setDraft({ ...draft, date: e.target.value })} />
|
||||
<JalaliDateInput value={draft.date} onChange={(date) => setDraft({ ...draft, date })} />
|
||||
</Field>
|
||||
<Field label="شرح سند">
|
||||
<Input value={draft.description} onChange={(e) => setDraft({ ...draft, description: e.target.value })} />
|
||||
|
||||
Reference in New Issue
Block a user