Enhance pricing validation and update related components
- Added validation logic in `UpdatePricingSettingsCommandValidator` to ensure the annual price does not fall below the equivalent quarterly price, preventing potential pricing discrepancies. - Updated `PricingSettings` model documentation to clarify that both pricing fields represent monthly rates, with calculations for total costs based on the number of months. - Modified frontend components to reflect the new validation, including error messages when the annual price is cheaper than the quarterly price. - Adjusted API documentation to accurately describe the pricing structure and validation rules for the pricing endpoints.
This commit is contained in:
@@ -20,8 +20,9 @@ function AdminRolesPage() {
|
||||
const { data, isLoading, isError, refetch } = useQuery({ queryKey: ['admin-roles'], queryFn: listRoles })
|
||||
const { data: pricing } = useQuery({ queryKey: ['admin-pricing'], queryFn: getPricingSettings })
|
||||
|
||||
const totalPrice = (price: number | null | undefined, maxConfigs: number) =>
|
||||
price == null || maxConfigs < 0 ? t('admin.roles.noPrice') : `${price * maxConfigs} ₽`
|
||||
// Ставки — цена за конфиг В МЕСЯЦ при данном тарифе; итог за период = ставка × месяцев × квота.
|
||||
const totalPrice = (monthlyRate: number | null | undefined, maxConfigs: number, months: number) =>
|
||||
monthlyRate == null || maxConfigs < 0 ? t('admin.roles.noPrice') : `${monthlyRate * months * maxConfigs} ₽`
|
||||
|
||||
const deleteMutation = useMutation({
|
||||
mutationFn: deleteRole,
|
||||
@@ -58,6 +59,7 @@ function AdminRolesPage() {
|
||||
<th className="py-2 font-medium">{t('admin.roles.maxConfigs')}</th>
|
||||
<th className="py-2 font-medium">{t('admin.roles.maxIpLimit')}</th>
|
||||
<th className="py-2 font-medium">{t('admin.roles.totalPerQuarter')}</th>
|
||||
<th className="py-2 font-medium">{t('admin.roles.totalHalfYear')}</th>
|
||||
<th className="py-2 font-medium">{t('admin.roles.totalPerYear')}</th>
|
||||
<th className="py-2" />
|
||||
<th className="py-2" />
|
||||
@@ -71,8 +73,9 @@ function AdminRolesPage() {
|
||||
</td>
|
||||
<td className="py-2">{role.maxConfigs < 0 ? t('unlimited') : role.maxConfigs}</td>
|
||||
<td className="py-2">{role.maxIpLimit < 0 ? t('unlimited') : role.maxIpLimit}</td>
|
||||
<td className="py-2">{totalPrice(pricing?.pricePerConfigPerQuarter, role.maxConfigs)}</td>
|
||||
<td className="py-2">{totalPrice(pricing?.pricePerConfigPerYear, role.maxConfigs)}</td>
|
||||
<td className="py-2">{totalPrice(pricing?.pricePerConfigPerQuarter, role.maxConfigs, 3)}</td>
|
||||
<td className="py-2">{totalPrice(pricing?.pricePerConfigPerQuarter, role.maxConfigs, 6)}</td>
|
||||
<td className="py-2">{totalPrice(pricing?.pricePerConfigPerYear, role.maxConfigs, 12)}</td>
|
||||
<td className="py-2 text-right">
|
||||
<Button size="sm" variant="outline" onClick={() => setEditing(role)}>
|
||||
{t('admin.roles.edit')}
|
||||
|
||||
Reference in New Issue
Block a user