НДС в DI2: линии начислено/вычет на графике, таблицы с прокруткой
- Динамика НДС (месяц): поверх столбцов «к уплате за месяц»/«накоплено за квартал» добавлены линии «Начислено» и «Вычет» - Трекер авансовых УПД: без лимита 15 (все ждущие), настоящая table с фиксированными колонками (table-fixed, truncate+title), видимы первые ~5 строк, дальше скролл внутри блока, шапка прилипает (sticky) - Контроль квартала: главная таблица и «Показать все» — то же оформление table + скролл
This commit is contained in:
@@ -801,6 +801,8 @@ function VatTab({ data, quarters, balance, sync, tracker, quarterControl }: {
|
||||
<>
|
||||
<Bar dataKey="toPay" name="К уплате за месяц" fill={COLORS.toPay} radius={[3, 3, 0, 0]} />
|
||||
<Bar dataKey="vatCumulative" name="Накоплено за квартал" fill={COLORS.cumulative} radius={[3, 3, 0, 0]} />
|
||||
<Line dataKey="accrued" name="Начислено" stroke={COLORS.income} strokeWidth={2} dot={{ r: 2 }} />
|
||||
<Line dataKey="deducted" name="Вычет" stroke={COLORS.expense} strokeWidth={2} dot={{ r: 2 }} />
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
@@ -836,23 +838,27 @@ function VatTab({ data, quarters, balance, sync, tracker, quarterControl }: {
|
||||
</CardHeader>
|
||||
<CardContent className="px-4 pb-4">
|
||||
{(tracker.rows ?? []).length > 0 ? (
|
||||
<div className="overflow-x-auto">
|
||||
<div className="min-w-[560px] space-y-1">
|
||||
<div className="grid grid-cols-[1.2fr_1fr_auto_auto] gap-3 text-xs text-muted-foreground pb-1 border-b border-border">
|
||||
<span>Поставщик</span>
|
||||
<span>Договор/счёт</span>
|
||||
<span className="text-right">Аванс выданный</span>
|
||||
<span className="text-right pr-2">Можем сбавить</span>
|
||||
</div>
|
||||
{tracker.rows.map((r: any, i: number) => (
|
||||
<div key={i} className="grid grid-cols-[1.2fr_1fr_auto_auto] gap-3 text-sm py-1 items-baseline">
|
||||
<span className="text-foreground truncate" title={r.supplier}>{r.supplier}</span>
|
||||
<span className="text-muted-foreground truncate" title={r.contract}>{formatContractDate(r.contract || "—")}</span>
|
||||
<span className="tabular-nums text-right text-muted-foreground">{formatCurrency(r.advanceOut)}</span>
|
||||
<span className="tabular-nums text-right font-medium text-foreground pr-2">{formatCurrency(r.potentialVat)}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="max-h-[264px] overflow-y-auto overflow-x-auto">
|
||||
<table className="w-full table-fixed text-sm">
|
||||
<thead className="sticky top-0 z-10 bg-background">
|
||||
<tr className="text-xs text-muted-foreground border-b border-border">
|
||||
<th className="text-left font-normal pb-1 w-[30%]">Поставщик</th>
|
||||
<th className="text-left font-normal pb-1 w-[30%]">Договор/счёт</th>
|
||||
<th className="text-right font-normal pb-1 w-[20%]">Аванс выданный</th>
|
||||
<th className="text-right font-normal pb-1 w-[20%] pr-2">Можем сбавить</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{tracker.rows.map((r: any, i: number) => (
|
||||
<tr key={i} className="border-b border-border/50">
|
||||
<td className="py-1.5 pr-3 truncate text-foreground" title={r.supplier}>{r.supplier}</td>
|
||||
<td className="py-1.5 pr-3 truncate text-muted-foreground" title={r.contract || undefined}>{formatContractDate(r.contract || "—")}</td>
|
||||
<td className="py-1.5 text-right tabular-nums text-muted-foreground">{formatCurrency(r.advanceOut)}</td>
|
||||
<td className="py-1.5 text-right tabular-nums font-medium text-foreground pr-2">{formatCurrency(r.potentialVat)}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
) : (
|
||||
<p className="text-sm text-muted-foreground">Все авансовые УПД получены — вычеты с выданных авансов исчерпаны</p>
|
||||
@@ -917,30 +923,36 @@ function VatTab({ data, quarters, balance, sync, tracker, quarterControl }: {
|
||||
{allContractsQuery.isLoading ? (
|
||||
<Skeleton className="h-[200px] rounded-xl" />
|
||||
) : (
|
||||
<div className="overflow-x-auto">
|
||||
<div className="min-w-[640px] space-y-1">
|
||||
<div className="grid grid-cols-[auto_1.3fr_1fr_auto_auto] gap-3 text-xs text-muted-foreground pb-1 border-b border-border items-center">
|
||||
<span className="w-2" />
|
||||
<span>Контрагент</span>
|
||||
<span>Договор</span>
|
||||
<span className="text-right">Оплачено</span>
|
||||
<span className="text-right pr-2">Аванс 62.02</span>
|
||||
</div>
|
||||
{allContractRows.map((r: any, i: number) => {
|
||||
const meta = MARKER_META[r.marker] ?? { label: r.marker, short: r.marker, color: "#94a3b8" };
|
||||
return (
|
||||
<div key={i} className="grid grid-cols-[auto_1.3fr_1fr_auto_auto] gap-3 text-sm py-1 items-baseline">
|
||||
<span className="w-2 h-2 rounded-full shrink-0" style={{ backgroundColor: meta.color }} title={meta.label} />
|
||||
<span className="text-foreground truncate" title={r.counterparty}>{r.counterparty}</span>
|
||||
<span className="text-muted-foreground truncate" title={r.contract || "Договор в документах не заполнен"}>
|
||||
{r.contract ? formatContractDate(r.contract) : "— договор не заполнен —"}
|
||||
</span>
|
||||
<span className="tabular-nums text-right text-foreground">{formatCurrency(r.paid)}</span>
|
||||
<span className="tabular-nums text-right text-muted-foreground pr-2">{formatCurrency(r.advanceBalance)}</span>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<div className="max-h-[320px] overflow-y-auto overflow-x-auto">
|
||||
<table className="w-full table-fixed text-sm">
|
||||
<thead className="sticky top-0 z-10 bg-background">
|
||||
<tr className="text-xs text-muted-foreground border-b border-border">
|
||||
<th className="text-left font-normal pb-1 w-5" />
|
||||
<th className="text-left font-normal pb-1 w-[30%]">Контрагент</th>
|
||||
<th className="text-left font-normal pb-1 w-[28%]">Договор</th>
|
||||
<th className="text-right font-normal pb-1 w-[20%]">Оплачено</th>
|
||||
<th className="text-right font-normal pb-1 w-[19%] pr-2">Аванс 62.02</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{allContractRows.map((r: any, i: number) => {
|
||||
const meta = MARKER_META[r.marker] ?? { label: r.marker, short: r.marker, color: "#94a3b8" };
|
||||
return (
|
||||
<tr key={i} className="border-b border-border/50">
|
||||
<td className="py-1.5 pr-2">
|
||||
<span className="block w-2 h-2 rounded-full shrink-0" style={{ backgroundColor: meta.color }} title={meta.label} />
|
||||
</td>
|
||||
<td className="py-1.5 pr-3 truncate text-foreground" title={r.counterparty}>{r.counterparty}</td>
|
||||
<td className="py-1.5 pr-3 truncate text-muted-foreground" title={r.contract || "Договор в документах не заполнен"}>
|
||||
{r.contract ? formatContractDate(r.contract) : "— договор не заполнен —"}
|
||||
</td>
|
||||
<td className="py-1.5 text-right tabular-nums text-foreground">{formatCurrency(r.paid)}</td>
|
||||
<td className="py-1.5 text-right tabular-nums text-muted-foreground pr-2">{formatCurrency(r.advanceBalance)}</td>
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
)}
|
||||
<Button variant="ghost" size="sm" className="h-6 px-2 text-xs" onClick={() => setShowAllContracts(false)}>
|
||||
@@ -950,25 +962,29 @@ function VatTab({ data, quarters, balance, sync, tracker, quarterControl }: {
|
||||
) : (
|
||||
<div className="space-y-3">
|
||||
{redHanging.length > 0 ? (
|
||||
<div className="overflow-x-auto">
|
||||
<div className="min-w-[640px] space-y-1">
|
||||
<div className="grid grid-cols-[1.3fr_1fr_auto_auto] gap-3 text-xs text-muted-foreground pb-1 border-b border-border">
|
||||
<span>Контрагент</span>
|
||||
<span>Договор</span>
|
||||
<span className="text-right">Оплачено с начала года</span>
|
||||
<span className="text-right pr-2">Аванс на 62.02</span>
|
||||
</div>
|
||||
{redHanging.map((r: any, i: number) => (
|
||||
<div key={i} className="grid grid-cols-[1.3fr_1fr_auto_auto] gap-3 text-sm py-1 items-baseline">
|
||||
<span className="text-foreground truncate" title={r.counterparty}>{r.counterparty}</span>
|
||||
<span className="text-muted-foreground truncate" title={r.contract || "Договор в документах не заполнен"}>
|
||||
{r.contract ? formatContractDate(r.contract) : "— договор не заполнен —"}
|
||||
</span>
|
||||
<span className="tabular-nums text-right font-medium text-foreground">{formatCurrency(r.paid)}</span>
|
||||
<span className="tabular-nums text-right text-muted-foreground pr-2">{formatCurrency(r.advanceBalance)}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="max-h-[264px] overflow-y-auto overflow-x-auto">
|
||||
<table className="w-full table-fixed text-sm">
|
||||
<thead className="sticky top-0 z-10 bg-background">
|
||||
<tr className="text-xs text-muted-foreground border-b border-border">
|
||||
<th className="text-left font-normal pb-1 w-[30%]">Контрагент</th>
|
||||
<th className="text-left font-normal pb-1 w-[30%]">Договор</th>
|
||||
<th className="text-right font-normal pb-1 w-[20%]">Оплачено с начала года</th>
|
||||
<th className="text-right font-normal pb-1 w-[20%] pr-2">Аванс на 62.02</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{redHanging.map((r: any, i: number) => (
|
||||
<tr key={i} className="border-b border-border/50">
|
||||
<td className="py-1.5 pr-3 truncate text-foreground" title={r.counterparty}>{r.counterparty}</td>
|
||||
<td className="py-1.5 pr-3 truncate text-muted-foreground" title={r.contract || "Договор в документах не заполнен"}>
|
||||
{r.contract ? formatContractDate(r.contract) : "— договор не заполнен —"}
|
||||
</td>
|
||||
<td className="py-1.5 text-right tabular-nums font-medium text-foreground">{formatCurrency(r.paid)}</td>
|
||||
<td className="py-1.5 text-right tabular-nums text-muted-foreground pr-2">{formatCurrency(r.advanceBalance)}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
) : (
|
||||
<p className="text-sm text-muted-foreground">Договоров с висячим авансом и без отгрузки нет</p>
|
||||
|
||||
@@ -255,8 +255,7 @@ export function registerNdsRoutes(app: Express): void {
|
||||
FROM nds_advance_vat_tracker
|
||||
WHERE snapshot_date = (SELECT MAX(snapshot_date) FROM nds_advance_vat_tracker)
|
||||
AND status = 'НЕТ АВАНСОВОЙ УПД'
|
||||
ORDER BY potential_vat DESC
|
||||
LIMIT 15`
|
||||
ORDER BY potential_vat DESC`
|
||||
)
|
||||
),
|
||||
]);
|
||||
|
||||
Reference in New Issue
Block a user