Найдено в catalog-edge: - DELETE контрагента, на которого ссылаются supplies/retail-sales/products (DefaultSupplier), отдавал 500 (DbUpdateException 23503) вместо понятного 409. Добавлен явный чек использования → Conflict со списком где занят. - POST товара с пустым Name проходил до FK-проверки и падал неинформативно; теперь явный 400 с указанием поля. На ProductInput навешены [Required]/[MinLength]/[StringLength] на Name/Article/ImageUrl — отсекаем пустые и сверхдлинные значения на уровне модели. catalog-edge: 12/12. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
99 lines
4.5 KiB
C#
99 lines
4.5 KiB
C#
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);
|
|
|
|
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,
|
|
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);
|