ui(products-list): колонки Штрихкод/Фасовка/Закупочная цена
В таблице товаров: - «Ед.» → «Фасовка» (packagingLabel из типа товара, sort packaging). - «Штрихкодов» (count) → «Штрихкод» — первый код монoshrift. - Убраны колонки «Группа» и «Активен». - Добавлена «Закупочная цена» с форматированием «305.00 ₸» (purchasePrice + purchaseCurrencyCode), sort purchasePrice. На сервере ProductsController.List принимает новые sort keys packaging и purchasePrice. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a94c38d074
commit
08816c60ca
|
|
@ -92,6 +92,10 @@ private async Task<decimal> ResolveDefaultVatAsync(CancellationToken ct)
|
||||||
("group", true) => q.OrderByDescending(p => p.ProductGroup != null ? p.ProductGroup.Name : null).ThenBy(p => p.Name),
|
("group", true) => q.OrderByDescending(p => p.ProductGroup != null ? p.ProductGroup.Name : null).ThenBy(p => p.Name),
|
||||||
("unit", false) => q.OrderBy(p => p.UnitOfMeasure!.Name).ThenBy(p => p.Name),
|
("unit", false) => q.OrderBy(p => p.UnitOfMeasure!.Name).ThenBy(p => p.Name),
|
||||||
("unit", true) => q.OrderByDescending(p => p.UnitOfMeasure!.Name).ThenBy(p => p.Name),
|
("unit", true) => q.OrderByDescending(p => p.UnitOfMeasure!.Name).ThenBy(p => p.Name),
|
||||||
|
("packaging", false) => q.OrderBy(p => p.Packaging).ThenBy(p => p.Name),
|
||||||
|
("packaging", true) => q.OrderByDescending(p => p.Packaging).ThenBy(p => p.Name),
|
||||||
|
("purchasePrice", false) => q.OrderBy(p => p.PurchasePrice).ThenBy(p => p.Name),
|
||||||
|
("purchasePrice", true) => q.OrderByDescending(p => p.PurchasePrice).ThenBy(p => p.Name),
|
||||||
("vat", false) => q.OrderBy(p => p.Vat).ThenBy(p => p.Name),
|
("vat", false) => q.OrderBy(p => p.Vat).ThenBy(p => p.Name),
|
||||||
("vat", true) => q.OrderByDescending(p => p.Vat).ThenBy(p => p.Name),
|
("vat", true) => q.OrderByDescending(p => p.Vat).ThenBy(p => p.Name),
|
||||||
("isActive", false) => q.OrderBy(p => p.IsActive).ThenBy(p => p.Name),
|
("isActive", false) => q.OrderBy(p => p.IsActive).ThenBy(p => p.Name),
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import { Plus, Filter, X } from 'lucide-react'
|
||||||
import { useCatalogList } from '@/lib/useCatalog'
|
import { useCatalogList } from '@/lib/useCatalog'
|
||||||
import { useOrgSettings } from '@/lib/useOrgSettings'
|
import { useOrgSettings } from '@/lib/useOrgSettings'
|
||||||
import { ProductGroupTree } from '@/components/ProductGroupTree'
|
import { ProductGroupTree } from '@/components/ProductGroupTree'
|
||||||
import type { Product } from '@/lib/types'
|
import { packagingLabel, type Product } from '@/lib/types'
|
||||||
|
|
||||||
const URL = '/api/catalog/products'
|
const URL = '/api/catalog/products'
|
||||||
|
|
||||||
|
|
@ -117,16 +117,19 @@ export function ProductsPage() {
|
||||||
{r.article && <div className="text-xs text-slate-400 font-mono">{r.article}</div>}
|
{r.article && <div className="text-xs text-slate-400 font-mono">{r.article}</div>}
|
||||||
</div>
|
</div>
|
||||||
)},
|
)},
|
||||||
{ header: 'Группа', width: '200px', sortKey: 'group', cell: (r) => r.productGroupName ?? '—' },
|
{ header: 'Фасовка', width: '110px', sortKey: 'packaging', cell: (r) => packagingLabel[r.packaging] ?? '—' },
|
||||||
{ header: 'Ед.', width: '70px', sortKey: 'unit', cell: (r) => r.unitName },
|
{ header: 'Штрихкод', width: '160px', cell: (r) => (
|
||||||
|
<span className="font-mono">{r.barcodes[0]?.code ?? '—'}</span>
|
||||||
|
)},
|
||||||
|
{ header: 'Закупочная цена', width: '160px', className: 'text-right font-mono', sortKey: 'purchasePrice', cell: (r) => (
|
||||||
|
r.purchasePrice != null
|
||||||
|
? `${r.purchasePrice.toLocaleString('ru', { minimumFractionDigits: 2, maximumFractionDigits: 2 })} ${r.purchaseCurrencyCode ?? ''}`.trim()
|
||||||
|
: '—'
|
||||||
|
)},
|
||||||
]
|
]
|
||||||
if (showVat) {
|
if (showVat) {
|
||||||
baseColumns.push({ header: 'НДС', width: '90px', className: 'text-right', sortKey: 'vat', cell: (r) => r.vatEnabled ? `${r.vat.toFixed(2)}%` : '—' })
|
baseColumns.push({ header: 'НДС', width: '90px', className: 'text-right', sortKey: 'vat', cell: (r) => r.vatEnabled ? `${r.vat.toFixed(2)}%` : '—' })
|
||||||
}
|
}
|
||||||
baseColumns.push(
|
|
||||||
{ header: 'Штрихкодов', width: '120px', className: 'text-right', cell: (r) => r.barcodes.length },
|
|
||||||
{ header: 'Активен', width: '100px', sortKey: 'isActive', cell: (r) => r.isActive ? '✓' : '—' },
|
|
||||||
)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex h-full min-h-0">
|
<div className="flex h-full min-h-0">
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue