Files
opensourcepos/app/Language/ru/Items.php
T
jekkosandobjecttothis 625bb3536a fix(taxes): reject negative tax rates and percentages (#4730)
* fix(taxes): reject negative tax rates and percentages

Reject negative tax values across all tax entry points so they can
never be persisted and produce inverted sales totals:

- Items::postSave / postBulkUpdate: validate tax_percents.* as
  nonNegativeDecimal (was unvalidated, persisted raw).
- Items::save_tax_data (CSV import): fail the row on a negative
  Tax N Percent instead of silently dropping the tax.
- Taxes::postSave: reject negative tax_rate before saving.
- Config::postSaveTax: reject negative default tax rates.

Adds non-negative regression tests for Items, Taxes and Config, plus
boundary tests proving a zero tax rate/percent is still accepted. New
language strings for the rejection messages.

* test: adopt test{Method}_{Purpose} naming convention for new tests

Align the negative-tax test method names with the convention established
in ConfigTest (testPostSave_RejectsNegativeTaxPercent, etc.), per review.

* fix(config): add language entries to all locales, extract TaxFixtureTrait

* fix(i18n): place tax_rate_non_negative in alphabetical order

Move the new tax_rate_non_negative entry to its correct alphabetical
position (after tax_rate_error_adding_updating) in all locale files.

---------

Co-authored-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-10-09 08:58:00 +02:00

126 lines
11 KiB
PHP
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.
<?php
return [
'add_minus' => 'Добавить/убрать товар.',
'allow_alt_description' => 'Разрешить альтернативные описания',
'amount_entry' => 'Ввод количества',
'bulk_edit' => 'Массовое редактирование',
'buy_price_required' => 'Цена покупки - обязательное поле.',
'cannot_be_deleted' => 'Не удалось удалить выбраннй(ые) товар(ы), так как у одного или нескольких выбранных товаров есть продажи.',
'cannot_find_item' => 'Товар не найден.',
'categories' => '',
'category' => 'Категория',
'category_new' => '',
'category_required' => 'Категория - обязательное поле.',
'change_all_to_allow_alt_desc' => 'Разрешить альтернативное описание для всех.',
'change_all_to_not_allow_allow_desc' => 'Не разрешать альтернативные описания для всех.',
'change_all_to_serialized' => 'Выбрать все',
'change_all_to_unserialized' => 'Снять выделение со всех',
'change_image' => 'Изменить изображение',
'confirm_bulk_edit' => 'Вы уверены, что хотите редактировать выбранные товары?',
'confirm_bulk_edit_wipe_taxes' => 'Вся информация о налогах на товар будет изменена.',
'confirm_delete' => 'Вы уверены, что хотите удалить выбранные товары?',
'confirm_restore' => 'Вы уверены, что хотите восстановить выбранные товары?',
'cost_price' => 'Оптовая цена',
'cost_price_number' => 'Оптовая цена должна быть числом.',
'cost_price_required' => 'Оптовая цена - обязательное поле.',
'count' => 'Обновление запасов',
'csv_import_failed' => 'Ошибка импорта CSV',
'csv_import_invalid_location' => '',
'csv_import_nodata_wrongformat' => 'Загруженный файл CSV не содержит данных или имеет неправильный формат.',
'csv_import_partially_failed' => 'В строке (строках) произошло {0} ошибок импорта: {1}. Ничего не было импортировано.',
'csv_import_success' => 'Товар успешно импортирован из CSV.',
'current_quantity' => 'Текущее количество',
'default_pack_name' => 'Каждый',
'description' => 'Описание',
'details_count' => 'Сведения о запасах',
'do_nothing' => 'Ничего не делать',
'edit' => '',
'edit_fields_you_want_to_update' => 'Отредактируйте нужные поля у выбранных товаров.',
'edit_multiple_items' => 'Редактирование нескольких товаров',
'empty_upc_items' => 'Штрих-код товара(ов) пуст',
'error_adding_updating' => 'Ошибка при добавлении/обновлении товара',
'error_updating_multiple' => 'Ошибка при обновлении товаров',
'generate_barcodes' => 'Генерация штрих-кодов',
'hsn_code' => 'Согласованная система номенклатуры',
'image' => 'Изображение',
'import_items_csv' => 'Импорт товаров из CSV',
'info_provided_by' => 'Информация предоставлена',
'inventory' => 'Запасы',
'inventory_CSV_import_quantity' => 'Импортированое количество из CSV',
'inventory_comments' => 'Комментарии',
'inventory_data_tracking' => 'Отслеживание запасов',
'inventory_date' => 'Дата',
'inventory_employee' => 'Сотрудник',
'inventory_in_out_quantity' => 'Количество (Приход / Уход)',
'inventory_remarks' => 'Пометки',
'is_deleted' => 'Удаленный',
'is_printed' => '',
'is_serialized' => 'Товар имеет серийный номер',
'item' => 'Товар',
'item_id' => '',
'item_number' => 'Штрих-код',
'item_number_duplicate' => 'Товар с таким номером уже присутствует в базе данных.',
'item_number_invalid' => 'Номер товара содержит недопустимые символы.',
'kit' => 'Комплект',
'location' => 'Расположение',
'low_inventory_items' => 'Товары не в наличии',
'low_sell_item' => 'Товар с низким уровнем продаж',
'manually_editing_of_quantity' => 'Ручное редактирование количества',
'markup' => '',
'name' => 'Название товара',
'name_required' => 'Название товара - обязательно для заполнения.',
'new' => 'Новый товар',
'no_description_items' => 'Нет описания товаров',
'no_items_to_display' => 'Нет товаров для отображения.',
'none' => 'Нет',
'none_selected' => 'Вы не выбрали ни одного товара для редактирования',
'nonstock' => 'Нет в наличии',
'number_information' => 'Номер товара',
'number_required' => 'Штрихкод - обязательное поле для заполнения.',
'one_or_multiple' => 'товар(ов)',
'pack_name' => 'Название упаковки',
'qty_per_pack' => 'Количество в упаковке',
'quantity' => 'Количество',
'quantity_number' => 'Количество должно быть числом.',
'quantity_required' => 'Количество - обязательное поле для заполнения.',
'receiving_quantity' => 'Количество закупок',
'remove_image' => 'Удалить изображение',
'reorder_level' => 'Уровень повторного заказа',
'reorder_level_number' => 'Уровень повторного заказа должно быть числом.',
'reorder_level_required' => 'Уровень повторного заказа - обязательное поле для заполнения.',
'retrive_item_info' => 'Информация о получении товара',
'sales_tax_1' => 'Налог на продажу',
'sales_tax_2' => 'Налог на продажу 2',
'search_attributes' => 'Поиск атрибутов',
'select_image' => 'Выбрать изображение',
'serialized_items' => 'Выбранные товары',
'standard' => 'Стандарт',
'stock' => 'В наличии',
'stock_location' => 'Расположение запасов',
'stock_type' => 'Наличие',
'successful_adding' => 'Вы успешно добавили товар',
'successful_bulk_edit' => 'Вы успешно обновили выбранный товар(ы)',
'successful_deleted' => 'Успешно удалено',
'successful_updating' => 'Товар успешно обновлен',
'supplier' => 'Поставщик',
'tax_1' => 'Налог 1',
'tax_2' => 'Налог 2',
'tax_3' => '',
'tax_category' => 'Категория налога',
'tax_name_invalid' => 'Название налога содержит недопустимые символы.',
'tax_percent' => 'процент налога',
'tax_percent_number' => 'Налоговый процент должен быть числом',
'tax_percent_non_negative' => '',
'tax_percent_required' => 'Налоговый процент - обязательно для заполнения.',
'tax_percents' => 'Налоговый процент',
'temp' => 'Временный',
'type' => 'Тип товара',
'unit_price' => 'Розничная цена',
'unit_price_number' => 'Розничная цена должна быть числом.',
'unit_price_required' => 'Розничная цена - обязательное поле для заполнения.',
'upc_database' => 'База данных штрих-кодов',
'update' => 'Обновление товара',
'use_inventory_menu' => 'Использовать меню запасов',
];