food-market/src/food-market.application/Catalog/CatalogDtos.cs
nns ac55da8d06 feat(pos): избранные товары (плитки) + переключатель тёмной темы
- Избранное: Product.IsFavorite/FavoriteOrder (миграция Phase37), в POS-синке
  (ProductSyncDto) и в карточке товара (ProductInput). Касса: PosStore хранит
  флаг (+ALTER для старых БД) и GetFavorites(); на экране продажи — сворачиваемая
  сетка плиток «быстрых товаров» (товары без штрихкода: хлеб, овощи на вес),
  тап добавляет в чек. Unit-тест GetFavorites (порядок/фильтр). 44 POS unit зелёные.
- Тёмная тема — опция: кнопка-переключатель в шапке (ToggleTheme), выбор
  сохраняется на устройстве (kv device.theme), применяется при старте. На тех же
  токенах (ThemeDictionaries Light/Dark). По умолчанию — светлая. Кадр «тёмная тема» в галерее.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 13:35:56 +05:00

105 lines
5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.ComponentModel.DataAnnotations;
using foodmarket.Domain.Catalog;
namespace foodmarket.Application.Catalog;
public record CountryDto(
Guid Id, string Code, string Name,
Guid? DefaultCurrencyId, string? DefaultCurrencyCode, string? DefaultCurrencySymbol,
decimal VatRate);
public record CurrencyDto(Guid Id, string Code, string Name, string Symbol);
public record UnitOfMeasureDto(
Guid Id, string Code, string Name, Guid? OrganizationId,
bool IsActive = true, bool IsEnabledForOrg = true);
public record PriceTypeDto(
Guid Id, string Name, bool IsRequired, bool IsSystem,
bool IsRetail, int SortOrder);
public record StoreDto(
Guid Id, string Name, string? Code, string? Address, string? Phone,
string? ManagerName, bool IsMain, bool IsActive);
public record RetailPointDto(
Guid Id, string Name, string? Code, Guid StoreId, string? StoreName,
string? Address, string? Phone, string? FiscalSerial, string? FiscalRegNumber, bool IsActive);
public record ProductGroupDto(
Guid Id, string Name, Guid? ParentId, string Path, int SortOrder,
decimal? MarkupPercent, Guid? OrganizationId);
public record CounterpartyDto(
Guid Id, string Name, string? LegalName, CounterpartyType Type,
string? Bin, string? Iin, string? TaxNumber, Guid? CountryId, string? CountryName,
string? Address, string? Phone, string? Email,
string? BankName, string? BankAccount, string? Bik, string? ContactPerson, string? Notes,
// Port sklad 06.10 §11: служебный «Поставщик не указан». UI сортирует
// в конец списка и ставит бейдж «служебный», delete запрещён на сервере.
bool IsPlaceholder = false);
public record ProductBarcodeDto(Guid Id, string Code, BarcodeType Type, bool IsPrimary);
public record ProductPriceDto(Guid Id, Guid PriceTypeId, string PriceTypeName, decimal Amount, Guid CurrencyId, string CurrencyCode);
public record ProductDto(
Guid Id, string Name, string? Article, string? Description,
Guid UnitOfMeasureId, string UnitName,
decimal Vat, bool VatEnabled,
Guid ProductGroupId, string ProductGroupName,
Guid? DefaultSupplierId, string? DefaultSupplierName,
Guid? CountryOfOriginId, string? CountryOfOriginName,
bool IsService, Packaging Packaging, bool IsMarked,
decimal? MinStock, decimal? MaxStock,
decimal? ReferencePrice, DateTime? ReferencePriceUpdatedAt,
Guid? PurchaseCurrencyId, string? PurchaseCurrencyCode,
decimal Cost, DateTime? LastSupplyAt,
string? ImageUrl,
// Sprint 19: bulk-операции «Архивировать» / «Снять с продажи».
bool IsArchived, bool IsAvailableForSale,
IReadOnlyList<ProductPriceDto> Prices,
IReadOnlyList<ProductBarcodeDto> Barcodes);
// Upsert payloads (input)
public record CountryInput(
string Code, string Name,
Guid? DefaultCurrencyId = null, decimal VatRate = 0m);
public record CurrencyInput(string Code, string Name, string Symbol);
public record UnitOfMeasureInput(string Code, string Name);
public record PriceTypeInput(
string Name, bool IsRequired = false,
bool IsRetail = false, int SortOrder = 0);
public record StoreInput(
string Name, string? Code,
string? Address = null, string? Phone = null, string? ManagerName = null,
bool IsMain = false, bool IsActive = true);
public record RetailPointInput(
string Name, string? Code, Guid StoreId,
string? Address = null, string? Phone = null,
string? FiscalSerial = null, string? FiscalRegNumber = null, bool IsActive = true);
public record ProductGroupInput(
string Name, Guid? ParentId, int SortOrder = 0,
[Range(0, 1000)] decimal? MarkupPercent = null);
public record CounterpartyInput(
string Name, string? LegalName, CounterpartyType Type,
string? Bin, string? Iin, string? TaxNumber, Guid? CountryId,
string? Address, string? Phone, string? Email,
string? BankName, string? BankAccount, string? Bik, string? ContactPerson, string? Notes);
public record ProductBarcodeInput(string Code, BarcodeType Type = BarcodeType.Ean13, bool IsPrimary = false);
public record ProductPriceInput(Guid PriceTypeId, [Range(0, 1e10)] decimal Amount, Guid CurrencyId);
public record ProductInput(
[Required, MinLength(1), StringLength(500)] string Name,
[StringLength(500)] string? Article,
string? Description,
Guid UnitOfMeasureId, [Range(0, 100)] decimal? Vat, bool VatEnabled,
Guid ProductGroupId, Guid? DefaultSupplierId, Guid? CountryOfOriginId,
bool IsService = false, Packaging Packaging = Packaging.Piece, bool IsMarked = false,
[Range(0, 1e10)] decimal? MinStock = null, [Range(0, 1e10)] decimal? MaxStock = null,
[Range(0, 1e10)] decimal? ReferencePrice = null, Guid? PurchaseCurrencyId = null,
[StringLength(1000)] string? ImageUrl = null,
IReadOnlyList<ProductPriceInput>? Prices = null,
IReadOnlyList<ProductBarcodeInput>? Barcodes = null,
bool IsFavorite = false, int FavoriteOrder = 0);