Files
objecttothis 6db3dde491 Bugfix tax names (#4677)
bugfix(items, validation): reject unsafe tax names and fix payments temp table collision

- Add unicode_alpha_numeric_punct rule (OSPOSRules) to allow accented/CJK
  chars in text fields while blocking HTML-unsafe chars (<, >) as
  defense-in-depth against injection
- Items controller: extract validateItemFields/validateBulkUpdateFields,
  validate tax_names on save and bulk update using new rule; add shared
  validateFields helper in Secure_Controller to DRY up validation +
  JSON error response
- Escape tax_group output in sales/quote.php and receipt_email.php views
  to harden output encoding at render time
- Rename sales_payments_temp -> sales_report_payments_temp (Summary_report)
  and -> sales_search_payments_temp (Sale model) to avoid name collision
  between concurrently-created temp tables
- AGENTS.md: document alignment rule for => columns when inserting new
  language keys

Tests:
- Add ItemsControllerTest covering postSave/bulkupdate tax_names validation
- Reject <, > in tax_names on /items/save and /items/bulkupdate
- Verify unicode and apostrophe-containing tax names are accepted
- Cover CSV import helpers: header generation (basic, multiple locations,
  attributes), stock-location/attribute header builders, get_csv_file
  parsing (plain, BOM-prefixed, multi-row)
- Validate required-header detection for import templates
- Remove outdated tax name test from SalesControllerTest
- Simplify Database class references in SalesControllerTest

i18n:
- Add tax_name_invalid translation to Items.php for 20+ locales, inserted
  alphabetically after tax_category in each file
- Normalize quote style in ar-EG/Items.php to single quotes
- Add ka/Items.php Georgian locale scaffold

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-09-01 10:59:29 +04:00

125 lines
8.9 KiB
PHP

<?php
return [
'add_minus' => 'Inventario a agregar/substraer.',
'allow_alt_description' => 'Permitir Descripción Alternativa',
'amount_entry' => 'Monto entrada',
'bulk_edit' => 'Edición Múltiple',
'buy_price_required' => 'Precio de Compra es requerido.',
'cannot_be_deleted' => 'No se pueden borrar los artículos seleccionados. Uno o más tiene(n) ventas.',
'cannot_find_item' => 'Articulo no encontrado.',
'categories' => 'Categorías. Seleccione el número de artículo.',
'category' => 'Categoría',
'category_new' => 'Nueva Categoría',
'category_required' => 'Categoría es requerido.',
'change_all_to_allow_alt_desc' => 'Permitir Descripción Alternativa para todos.',
'change_all_to_not_allow_allow_desc' => 'No permitir descripción alternativa para todos.',
'change_all_to_serialized' => 'Cambiar Todo A Serializado',
'change_all_to_unserialized' => 'Cambiar Todo A Deserializado',
'change_image' => 'Cambiar Imagen',
'confirm_bulk_edit' => '¿Estás seguro(a) de querer editar los artículos seleccionados?',
'confirm_bulk_edit_wipe_taxes' => 'Toda la información de impuesto del articulo sera cambiada.',
'confirm_delete' => '¿Estás seguro(a) de querer borrar los artículos seleccionados?',
'confirm_restore' => 'Esta seguro de querer restaurar lo(s) articulo(s) seleccionada(s)?',
'cost_price' => 'Precio al Por Mayor',
'cost_price_number' => 'Precio al Por Mayor debe ser un número.',
'cost_price_required' => 'Precio al Por Mayor es un campo requerido.',
'count' => 'Actualizar Inventario',
'csv_import_failed' => 'Falló la importación de Hoja de Cálculo',
'csv_import_invalid_location' => 'Se encontraron ubicaciones de stock no válidas: {0}. Solo se permiten ubicaciones de stock válidas.',
'csv_import_nodata_wrongformat' => 'El archivo subido no tiene datos o el formato es incorrecto.',
'csv_import_partially_failed' => 'Hubo {0} falla(s) en la importación de producto(s) en la(s) línea(s): {1}. Ninguna fila ha sido importada.',
'csv_import_success' => 'Se importaron los articulos exitosamente.',
'current_quantity' => 'Cantidad Actual',
'default_pack_name' => 'Cada',
'description' => 'Descripción',
'details_count' => 'Detalles de Cuenta de Inventario',
'do_nothing' => 'No Hacer Nada',
'edit' => 'Editar',
'edit_fields_you_want_to_update' => 'Edita los campos para actualizar en los artículos seleccionados.',
'edit_multiple_items' => 'Editando Artículos Múltiples',
'empty_upc_items' => 'Items con UPC Vacio',
'error_adding_updating' => 'Error agregando/actualizando artículo',
'error_updating_multiple' => 'Error actualizando artículos',
'generate_barcodes' => 'Generar Códigos de Barras',
'hsn_code' => 'Nomenclatura de Sistemas Harmonizados',
'image' => 'Avatar',
'import_items_csv' => 'Importar Artículos desde CSV',
'info_provided_by' => 'Info provista por',
'inventory' => 'Inventario',
'inventory_CSV_import_quantity' => 'Catidad Importada desde CSV',
'inventory_comments' => 'Comentarios',
'inventory_data_tracking' => 'Seguimiento de datos de inventario',
'inventory_date' => 'Fecha',
'inventory_employee' => 'Empleado',
'inventory_in_out_quantity' => 'Cantidad E/S',
'inventory_remarks' => 'Observaciones',
'is_deleted' => 'Eliminado',
'is_printed' => 'No impreso',
'is_serialized' => 'El Artículo tiene Número de Serie',
'item' => 'Artículo',
'item_id' => 'Id del Artículo',
'item_number' => 'UPC/EAN/ISBN',
'item_number_duplicate' => 'El número de artículo ya esta presente en la base de datos.',
'item_number_invalid' => 'El número de artículo contiene caracteres no permitidos.',
'kit' => 'Kits de artículos',
'location' => 'Ubicación',
'low_inventory_items' => 'Artículos de Inventario Escaso',
'low_sell_item' => 'Producto de bajas ventas',
'manually_editing_of_quantity' => 'Edición Manual de Cantidad',
'markup' => 'El marcado de elementos está habilitado',
'name' => 'Nombre Artículo',
'name_required' => 'Nombre de Artículo es requerido.',
'new' => 'Nuevo Artículo',
'no_description_items' => 'Artículos sin Descripción',
'no_items_to_display' => 'Sin datos que mostrar.',
'none' => 'Ninguno',
'none_selected' => 'No has seleccionado artículos para editar',
'nonstock' => 'Sin stock',
'number_information' => 'Número del Artículo',
'number_required' => 'UPC/EAN/ISBN es un campo requerido.',
'one_or_multiple' => 'articulo(s)',
'pack_name' => 'Nombre del Paquete',
'qty_per_pack' => 'Cantidad por Paquete',
'quantity' => 'Cantidad en Stock',
'quantity_number' => 'Cantidad debe ser número.',
'quantity_required' => 'Cantidad es requerido.',
'receiving_quantity' => 'Cantidad Recibida',
'remove_image' => 'Quitar Imagen',
'reorder_level' => 'Cantidad Mínima',
'reorder_level_number' => 'Cantidad Mínima debe ser número.',
'reorder_level_required' => 'Cantidad Mínima es requerido.',
'retrive_item_info' => 'Obtener Información de Artículo',
'sales_tax_1' => 'Impuesto de Ventas 1',
'sales_tax_2' => 'Impuesto de Ventas 2',
'search_attributes' => 'Atributos de Búsqueda',
'select_image' => 'Seleccionar Imagen',
'serialized_items' => 'Artículos Serializados',
'standard' => 'Estándar',
'stock' => 'Existencia',
'stock_location' => 'Ubicación de Inventario',
'stock_type' => 'Tipo de stock',
'successful_adding' => 'Has agregado satisfactoriamente un artículo',
'successful_bulk_edit' => 'Has actualizado satisfactoriamente los artículos seleccionados',
'successful_deleted' => 'Has borrado satisfactoriamente',
'successful_updating' => 'Has actualizando satisfactoriamente un artículo',
'supplier' => 'Proveedor',
'tax_1' => 'Impuesto 1',
'tax_2' => 'Impuesto 2',
'tax_3' => 'Impuestos 3',
'tax_category' => 'Categoría del Impuesto',
'tax_name_invalid' => 'El nombre del impuesto contiene caracteres no permitidos.',
'tax_percent' => 'Porcentaje de Impuesto',
'tax_percent_number' => 'Impuesto porcentaje debe ser numerico',
'tax_percent_required' => 'Porcentaje de Impuesto es requerido.',
'tax_percents' => 'Porcentaje de Impuesto(s)',
'temp' => 'Temporal',
'type' => 'Tipo de ítem',
'unit_price' => 'Precio de Venta',
'unit_price_number' => 'Precio de Venta debe ser número.',
'unit_price_required' => 'Precio de Venta es requerido.',
'upc_database' => 'Base de datos UPC',
'update' => 'Actualizar Artículo',
'use_inventory_menu' => 'Usar Menú de Inventario',
];