feat(org-settings): валюта read-only, тянется из страны (как НДС)
Some checks are pending
CI / POS (WPF, Windows) (push) Waiting to run
CI / Backend (.NET 8) (push) Successful in 30s
CI / Web (React + Vite) (push) Successful in 22s
Docker Images / API image (push) Successful in 40s
Docker Images / Web image (push) Successful in 24s
Docker Images / Deploy stage (push) Successful in 11s
Some checks are pending
CI / POS (WPF, Windows) (push) Waiting to run
CI / Backend (.NET 8) (push) Successful in 30s
CI / Web (React + Vite) (push) Successful in 22s
Docker Images / API image (push) Successful in 40s
Docker Images / Web image (push) Successful in 24s
Docker Images / Deploy stage (push) Successful in 11s
- Currency в настройках больше не выбирается, показывается disabled как "KZT (₸)", источник правды — Country.DefaultCurrencyId. - Backend: OrgSettingsInput больше не принимает DefaultCurrencyId; Update синхронизирует Organization.DefaultCurrencyId со страной. - UX: страна — единственный редактируемый вход, определяет и НДС, и валюту. - Мульти-валютный режим (Organization.MultiCurrencyEnabled) остаётся галкой; выбор валюты в закупках/продажах/карточке товара по-прежнему скрыт когда флаг выключен. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
9d8c386def
commit
51bef16758
|
|
@ -32,10 +32,10 @@ public record OrgSettingsDto(
|
||||||
decimal VatRate,
|
decimal VatRate,
|
||||||
bool ShowVatEnabledOnProduct);
|
bool ShowVatEnabledOnProduct);
|
||||||
|
|
||||||
|
// DefaultCurrencyId не принимается — он read-only, выводится из страны (Country.DefaultCurrencyId).
|
||||||
public record OrgSettingsInput(
|
public record OrgSettingsInput(
|
||||||
string Name,
|
string Name,
|
||||||
string CountryCode,
|
string CountryCode,
|
||||||
Guid? DefaultCurrencyId,
|
|
||||||
bool MultiCurrencyEnabled,
|
bool MultiCurrencyEnabled,
|
||||||
bool ShowVatEnabledOnProduct);
|
bool ShowVatEnabledOnProduct);
|
||||||
|
|
||||||
|
|
@ -62,7 +62,11 @@ public async Task<ActionResult<OrgSettingsDto>> Update([FromBody] OrgSettingsInp
|
||||||
|
|
||||||
o.Name = input.Name;
|
o.Name = input.Name;
|
||||||
o.CountryCode = input.CountryCode;
|
o.CountryCode = input.CountryCode;
|
||||||
o.DefaultCurrencyId = input.DefaultCurrencyId;
|
// Валюта организации жёстко следует за страной — не принимается от клиента.
|
||||||
|
o.DefaultCurrencyId = await _db.Countries
|
||||||
|
.Where(c => c.Code == input.CountryCode)
|
||||||
|
.Select(c => c.DefaultCurrencyId)
|
||||||
|
.FirstOrDefaultAsync(ct);
|
||||||
o.MultiCurrencyEnabled = input.MultiCurrencyEnabled;
|
o.MultiCurrencyEnabled = input.MultiCurrencyEnabled;
|
||||||
o.ShowVatEnabledOnProduct = input.ShowVatEnabledOnProduct;
|
o.ShowVatEnabledOnProduct = input.ShowVatEnabledOnProduct;
|
||||||
await _db.SaveChangesAsync(ct);
|
await _db.SaveChangesAsync(ct);
|
||||||
|
|
|
||||||
|
|
@ -5,31 +5,27 @@ import { api } from '@/lib/api'
|
||||||
import { PageHeader } from '@/components/PageHeader'
|
import { PageHeader } from '@/components/PageHeader'
|
||||||
import { Button } from '@/components/Button'
|
import { Button } from '@/components/Button'
|
||||||
import { Field, TextInput, Select, Checkbox } from '@/components/Field'
|
import { Field, TextInput, Select, Checkbox } from '@/components/Field'
|
||||||
import { useCurrencies, useCountries } from '@/lib/useLookups'
|
import { useCountries } from '@/lib/useLookups'
|
||||||
import { useOrgSettings, type OrgSettings } from '@/lib/useOrgSettings'
|
import { useOrgSettings, type OrgSettings } from '@/lib/useOrgSettings'
|
||||||
|
|
||||||
export function OrganizationSettingsPage() {
|
export function OrganizationSettingsPage() {
|
||||||
const qc = useQueryClient()
|
const qc = useQueryClient()
|
||||||
const settings = useOrgSettings()
|
const settings = useOrgSettings()
|
||||||
const currencies = useCurrencies()
|
|
||||||
const countries = useCountries()
|
const countries = useCountries()
|
||||||
|
|
||||||
const [form, setForm] = useState<OrgSettings | null>(null)
|
const [form, setForm] = useState<OrgSettings | null>(null)
|
||||||
useEffect(() => { if (settings.data && !form) setForm(settings.data) }, [settings.data, form])
|
useEffect(() => { if (settings.data && !form) setForm(settings.data) }, [settings.data, form])
|
||||||
|
|
||||||
// При смене страны подтягиваем её валюту и ставку НДС (оба из справочника стран).
|
// При смене страны подтягиваем её валюту и ставку НДС (оба read-only, из справочника стран).
|
||||||
const onCountryChange = (countryCode: string) => {
|
const onCountryChange = (countryCode: string) => {
|
||||||
if (!form) return
|
if (!form) return
|
||||||
const country = countries.data?.find((c) => c.code === countryCode)
|
const country = countries.data?.find((c) => c.code === countryCode)
|
||||||
const currency = country?.defaultCurrencyId
|
|
||||||
? currencies.data?.find((c) => c.id === country.defaultCurrencyId)
|
|
||||||
: undefined
|
|
||||||
setForm({
|
setForm({
|
||||||
...form,
|
...form,
|
||||||
countryCode,
|
countryCode,
|
||||||
defaultCurrencyId: currency?.id ?? country?.defaultCurrencyId ?? null,
|
defaultCurrencyId: country?.defaultCurrencyId ?? null,
|
||||||
defaultCurrencyCode: currency?.code ?? country?.defaultCurrencyCode ?? null,
|
defaultCurrencyCode: country?.defaultCurrencyCode ?? null,
|
||||||
defaultCurrencySymbol: currency?.symbol ?? country?.defaultCurrencySymbol ?? null,
|
defaultCurrencySymbol: country?.defaultCurrencySymbol ?? null,
|
||||||
vatRate: country?.vatRate ?? 0,
|
vatRate: country?.vatRate ?? 0,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -40,7 +36,6 @@ export function OrganizationSettingsPage() {
|
||||||
const payload = {
|
const payload = {
|
||||||
name: form.name,
|
name: form.name,
|
||||||
countryCode: form.countryCode,
|
countryCode: form.countryCode,
|
||||||
defaultCurrencyId: form.defaultCurrencyId,
|
|
||||||
multiCurrencyEnabled: form.multiCurrencyEnabled,
|
multiCurrencyEnabled: form.multiCurrencyEnabled,
|
||||||
showVatEnabledOnProduct: form.showVatEnabledOnProduct,
|
showVatEnabledOnProduct: form.showVatEnabledOnProduct,
|
||||||
}
|
}
|
||||||
|
|
@ -71,17 +66,10 @@ export function OrganizationSettingsPage() {
|
||||||
</Select>
|
</Select>
|
||||||
</Field>
|
</Field>
|
||||||
<Field label="Валюта по умолчанию">
|
<Field label="Валюта по умолчанию">
|
||||||
<Select
|
<TextInput
|
||||||
value={form.defaultCurrencyId ?? ''}
|
value={form.defaultCurrencyCode ? `${form.defaultCurrencyCode} (${form.defaultCurrencySymbol ?? ''})` : '—'}
|
||||||
onChange={(e) => {
|
disabled
|
||||||
const id = e.target.value
|
/>
|
||||||
const c = currencies.data?.find((x) => x.id === id)
|
|
||||||
setForm({ ...form, defaultCurrencyId: id || null, defaultCurrencyCode: c?.code ?? null, defaultCurrencySymbol: c?.symbol ?? null })
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<option value="">—</option>
|
|
||||||
{currencies.data?.map((c) => <option key={c.id} value={c.id}>{c.code} ({c.symbol})</option>)}
|
|
||||||
</Select>
|
|
||||||
</Field>
|
</Field>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue