From 08816c60caca74c399b0171cd0067d2516fe9982 Mon Sep 17 00:00:00 2001 From: nns <278048682+nurdotnet@users.noreply.github.com> Date: Fri, 24 Apr 2026 19:03:45 +0500 Subject: [PATCH] =?UTF-8?q?ui(products-list):=20=D0=BA=D0=BE=D0=BB=D0=BE?= =?UTF-8?q?=D0=BD=D0=BA=D0=B8=20=D0=A8=D1=82=D1=80=D0=B8=D1=85=D0=BA=D0=BE?= =?UTF-8?q?=D0=B4/=D0=A4=D0=B0=D1=81=D0=BE=D0=B2=D0=BA=D0=B0/=D0=97=D0=B0?= =?UTF-8?q?=D0=BA=D1=83=D0=BF=D0=BE=D1=87=D0=BD=D0=B0=D1=8F=20=D1=86=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit В таблице товаров: - «Ед.» → «Фасовка» (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) --- .../Controllers/Catalog/ProductsController.cs | 4 ++++ src/food-market.web/src/pages/ProductsPage.tsx | 17 ++++++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/food-market.api/Controllers/Catalog/ProductsController.cs b/src/food-market.api/Controllers/Catalog/ProductsController.cs index 3ab04b6..b07a341 100644 --- a/src/food-market.api/Controllers/Catalog/ProductsController.cs +++ b/src/food-market.api/Controllers/Catalog/ProductsController.cs @@ -92,6 +92,10 @@ private async Task ResolveDefaultVatAsync(CancellationToken ct) ("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", 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", true) => q.OrderByDescending(p => p.Vat).ThenBy(p => p.Name), ("isActive", false) => q.OrderBy(p => p.IsActive).ThenBy(p => p.Name), diff --git a/src/food-market.web/src/pages/ProductsPage.tsx b/src/food-market.web/src/pages/ProductsPage.tsx index de7db62..3a13beb 100644 --- a/src/food-market.web/src/pages/ProductsPage.tsx +++ b/src/food-market.web/src/pages/ProductsPage.tsx @@ -8,7 +8,7 @@ import { Plus, Filter, X } from 'lucide-react' import { useCatalogList } from '@/lib/useCatalog' import { useOrgSettings } from '@/lib/useOrgSettings' import { ProductGroupTree } from '@/components/ProductGroupTree' -import type { Product } from '@/lib/types' +import { packagingLabel, type Product } from '@/lib/types' const URL = '/api/catalog/products' @@ -117,16 +117,19 @@ export function ProductsPage() { {r.article &&
{r.article}
} )}, - { header: 'Группа', width: '200px', sortKey: 'group', cell: (r) => r.productGroupName ?? '—' }, - { header: 'Ед.', width: '70px', sortKey: 'unit', cell: (r) => r.unitName }, + { header: 'Фасовка', width: '110px', sortKey: 'packaging', cell: (r) => packagingLabel[r.packaging] ?? '—' }, + { header: 'Штрихкод', width: '160px', cell: (r) => ( + {r.barcodes[0]?.code ?? '—'} + )}, + { 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) { 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 (