food-market/src/food-market.infrastructure/Persistence/Migrations/20260424062000_Phase5_VatAsCountryProperty.cs
nurdotnet 6979599791 feat(vat): ставка в стране + опц. переопределение на товаре
Phase5_VatAsCountryProperty:
- countries.VatRate (numeric(5,2)) — ставка страны, источник правды.
  Seed: KZ=16, RU=20, BY=20, DE=19, CN=13, TR=18, UZ=12, KG=12, KR=10,
  IT=22, PL=23, US=0.
- organizations.ShowVatEnabledOnProduct (bool, default false) — флаг
  отображения на карточке товара.
- organizations.DefaultVat удалён (заменён страной).
- products.Vat ОСТАЁТСЯ: для KZ есть льготные категории (хлеб/молоко =
  0%) и фискальный чек требует ставку на каждой позиции.

Country domain: + DefaultCurrency / VatRate (уже было DefaultCurrencyId
из Phase4, сейчас дополнено).

Organization domain: DefaultVat убран, ShowVatEnabledOnProduct добавлен.

Backend:
- ProductInput.Vat теперь int? — если UI скрывает поле и прислал null,
  ProductsController берёт дефолт из страны организации (Country.VatRate
  при создании; при update сохраняет прежнее значение).
- CountriesController.List/Get/Create/Update возвращает/принимает
  DefaultCurrency и VatRate.
- OtherSystem импорт: дефолт Vat загружается из страны организации.
- SystemReferenceSeeder: новые валюты BYN/UZS/KGS/TRY/KRW/PLN, seed
  country-currency-vat для всех 12 стран.
- OrganizationSettingsController: VatRate read-only из страны,
  ShowVatEnabledOnProduct редактируется.

Web:
- Country type + CountriesPage форма редактирования (валюта, ставка НДС).
- OrganizationSettingsPage: "Ставка НДС" read-only
  (берётся из страны, ссылка на /catalog/countries), галочка
  "Указывать ставку НДС на товаре".
- ProductEditPage: блок Ставка НДС % + галка "В том числе НДС" теперь
  показываются только если showVatEnabledOnProduct=true. В payload
  при save.mutate отправляется vat=null если скрыто.
- ProductsPage: колонка НДС показывается только при включённом флаге.

Galleries/products/settings других этапов — не задеты.
2026-04-24 11:56:28 +05:00

59 lines
2.7 KiB
C#

using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace foodmarket.Infrastructure.Persistence.Migrations
{
/// <summary>VAT теперь основывается на стране, но хранится и на товаре:
/// - countries.VatRate (numeric(5,2), default 0) — ставка страны, источник правды.
/// - organizations.ShowVatEnabledOnProduct (bool, default false) — показывать ли
/// поля Vat/VatEnabled на карточке товара в UI; внутренне они есть всегда.
/// - organizations.DefaultVat (int) удаляется (заменён на Country.VatRate).
/// - products.Vat ОСТАЁТСЯ: для KZ есть льготные категории (хлеб/молоко/
/// лекарства = 0%) и фискальный чек требует ставку на каждой позиции.
/// Seed: KZ=16%, RU=20%, BY=20%, US=0%, DE=19%, CN=13%, TR=18%, UZ=12%, KG=12%,
/// KR=10%, IT=22%, PL=23%.</summary>
public partial class Phase5_VatAsCountryProperty : Migration
{
protected override void Up(MigrationBuilder b)
{
b.AddColumn<decimal>(
name: "VatRate", schema: "public", table: "countries",
type: "numeric(5,2)", precision: 5, scale: 2, nullable: false, defaultValue: 0m);
b.AddColumn<bool>(
name: "ShowVatEnabledOnProduct", schema: "public", table: "organizations",
type: "boolean", nullable: false, defaultValue: false);
b.DropColumn(name: "DefaultVat", schema: "public", table: "organizations");
b.Sql("""
UPDATE public.countries SET "VatRate" = CASE "Code"
WHEN 'KZ' THEN 16
WHEN 'RU' THEN 20
WHEN 'BY' THEN 20
WHEN 'DE' THEN 19
WHEN 'CN' THEN 13
WHEN 'TR' THEN 18
WHEN 'UZ' THEN 12
WHEN 'KG' THEN 12
WHEN 'KR' THEN 10
WHEN 'IT' THEN 22
WHEN 'PL' THEN 23
ELSE 0
END;
""");
}
protected override void Down(MigrationBuilder b)
{
b.AddColumn<int>(
name: "DefaultVat", schema: "public", table: "organizations",
type: "integer", nullable: false, defaultValue: 16);
b.DropColumn(name: "ShowVatEnabledOnProduct", schema: "public", table: "organizations");
b.DropColumn(name: "VatRate", schema: "public", table: "countries");
}
}
}