Files
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
8.3 KiB
PHP

<?php
return [
'add_minus' => 'Lager att lägga till eller ta bort.',
'allow_alt_description' => 'Tillåt alternativ beskrivning',
'amount_entry' => 'Belopp',
'bulk_edit' => 'Massändra',
'buy_price_required' => 'Köppriset är ett obligatoriskt fält.',
'cannot_be_deleted' => 'Kunde inte radera valda objekt, en eller flera av de valda objekten har försäljning.',
'cannot_find_item' => 'Artikeln hittades inte.',
'categories' => '',
'category' => 'Kategori',
'category_new' => '',
'category_required' => 'Kategori är ett obligatoriskt fält.',
'change_all_to_allow_alt_desc' => 'Tillåt alternativ beskrivning för alla.',
'change_all_to_not_allow_allow_desc' => 'Tillåt inte alternativ beskrivning för alla.',
'change_all_to_serialized' => 'Ändra allt till Serialized',
'change_all_to_unserialized' => 'Ändra allt till ej Serialized',
'change_image' => 'Ändra bild',
'confirm_bulk_edit' => 'Är du säker på att du vill redigera valda artiklar?',
'confirm_bulk_edit_wipe_taxes' => 'All Artikel Skatteinformation kommer att ersättas.',
'confirm_delete' => 'Är du säker på att du vill radera valda artiklar?',
'confirm_restore' => 'Är du säker på att du vill återställa valda artiklar?',
'cost_price' => 'Grossistpris',
'cost_price_number' => 'Grosistpriset måste vara ett nummer.',
'cost_price_required' => 'Grossistpris är ett obligatoriskt fält.',
'count' => 'Uppdatera Inventory',
'csv_import_failed' => 'CSV-import misslyckades',
'csv_import_invalid_location' => '',
'csv_import_nodata_wrongformat' => 'Den uppladdade filen har ingen data eller är formaterad felaktigt.',
'csv_import_partially_failed' => 'Det fanns{0} importfel (er) på rad (er):{1}. Inga rader importerades.',
'csv_import_success' => 'Artikelimporten lyckades.',
'current_quantity' => 'Nuvarande antal',
'default_pack_name' => 'Varje',
'description' => 'Beskrivning',
'details_count' => 'Inventarieringsuppgifter',
'do_nothing' => 'Gör ingeting',
'edit' => '',
'edit_fields_you_want_to_update' => 'Redigera önskade fält för valda artiklar.',
'edit_multiple_items' => 'Redigering av flera artiklar',
'empty_upc_items' => 'Tomma streckkodsposter',
'error_adding_updating' => 'Det gick inte att lägga till / uppdatera artiklar',
'error_updating_multiple' => 'Ett fel uppstod vid uppdatering av artiklar',
'generate_barcodes' => 'Generera streckkoder',
'hsn_code' => 'Harmoniserade systemnomenklaturen',
'image' => 'Avatar',
'import_items_csv' => 'Artikelimport från CSV',
'info_provided_by' => 'Information tillhandahållen av',
'inventory' => 'Lager',
'inventory_CSV_import_quantity' => 'Antal importerat från CSV',
'inventory_comments' => 'Kommentarer',
'inventory_data_tracking' => 'Lagerspårning',
'inventory_date' => 'Datum',
'inventory_employee' => 'Anställd',
'inventory_in_out_quantity' => 'In / Out Mängd',
'inventory_remarks' => 'Anmärkningar',
'is_deleted' => 'Raderad',
'is_printed' => '',
'is_serialized' => 'Artikeln har serienummer',
'item' => 'Artikel',
'item_id' => '',
'item_number' => 'Streckkod',
'item_number_duplicate' => 'Artikelnummer finns redan i databasen.',
'item_number_invalid' => 'Artikelnumret innehåller otillåtna tecken.',
'kit' => 'Kit',
'location' => 'Lagerplats',
'low_inventory_items' => 'Artikeln slutsåld',
'low_sell_item' => 'Låg försäljnings artikel',
'manually_editing_of_quantity' => 'Manuell redigering av antal',
'markup' => '',
'name' => 'Artikelnamn',
'name_required' => 'Artikelnamn är ett obligatoriskt fält.',
'new' => 'Ny artikel',
'no_description_items' => 'Inga beskrivning av artikel',
'no_items_to_display' => 'Inga artiklar att visa.',
'none' => 'inga',
'none_selected' => 'Du har inte valt några artiklar att redigera',
'nonstock' => 'Icke-lager',
'number_information' => 'Artikelnummer',
'number_required' => 'Streckkod är ett obligatoriskt fält.',
'one_or_multiple' => 'Artikel',
'pack_name' => 'Förpackningsnamn',
'qty_per_pack' => 'Antal per förpackning',
'quantity' => 'Kvantitet',
'quantity_number' => 'Antal måste vara ett nummer.',
'quantity_required' => 'Antal är ett obligatoriskt fält.',
'receiving_quantity' => 'Mottagningskvantitet',
'remove_image' => 'Radera bild',
'reorder_level' => 'Nivå för ombeställning',
'reorder_level_number' => 'Omordningsnivå måste vara ett nummer.',
'reorder_level_required' => 'Återbeställningsnivå är ett obligatoriskt fält.',
'retrive_item_info' => 'Hämta artikelinfo',
'sales_tax_1' => 'Moms',
'sales_tax_2' => 'Moms 2',
'search_attributes' => 'Sök attribut',
'select_image' => 'Välj Bild',
'serialized_items' => 'Serialiserade artiklar',
'standard' => 'Standard',
'stock' => 'Lager',
'stock_location' => 'Lagerplats',
'stock_type' => 'Lagertyp',
'successful_adding' => 'Du har lagt till Artikeln',
'successful_bulk_edit' => 'Du har uppdaterat den valda atikeln',
'successful_deleted' => 'Du har tagit bort artikeln',
'successful_updating' => 'Du har uppdaterat artikeln',
'supplier' => 'Leverantör',
'tax_1' => 'Skatt 1',
'tax_2' => 'Skatt 2',
'tax_3' => '',
'tax_category' => 'Skattekategori',
'tax_name_invalid' => 'Skattenamnet innehåller otillåtna tecken.',
'tax_percent' => 'Skatt %',
'tax_percent_number' => 'Skattprocent måste vara ett numeriskt värde',
'tax_percent_non_negative' => '',
'tax_percent_required' => 'Skattprocent är ett obligatoriskt fält.',
'tax_percents' => 'Skatt %',
'temp' => 'Tillfällig',
'type' => 'Artikeltyp',
'unit_price' => 'Försäljningspris',
'unit_price_number' => 'Enhetspriset måste vara ett nummer.',
'unit_price_required' => 'Enhetspriset är ett obligatoriskt fält.',
'upc_database' => 'Streckkod databas',
'update' => 'Uppdatera artikeln',
'use_inventory_menu' => 'Använd Inventory Menu',
];