Files
opensourcepos/app/Language/tr/Sales.php
Nozomu Sasaki (Paul) 85c7ce2da4 Fix negative price/quantity/discount validation (GHSA-wv3j-pp8r-7q43) (#4450)
* Fix business logic vulnerability allowing negative sale totals (GHSA-wv3j-pp8r-7q43)

Add server-side validation in postEditItem() to reject negative prices,
quantities, and discounts, as well as percentage discounts exceeding 100%
and fixed discounts exceeding the item total. Also block sale completion
with negative totals in non-return mode to prevent fraud/theft.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Fix: exempt return mode from negative quantity validation

Return mode legitimately stores items with negative quantities.
The quantity validation now skips the non-negative check in return mode,
consistent with the existing return mode exemption in postComplete().
Also use abs() for fixed discount comparison to handle return quantities.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Refactor: use $rules + validate() pattern per review feedback

Address review comments from jekkos on PR #4450:

1. Use CI4 $rules variable with custom non_negative_decimal validation
   rule instead of manual if-checks for price/discount validation.

2. Add validation error strings to all 44 non-English language files
   (English fallback values used until translations are contributed).

3. Use validate() method with $messages array for localized error
   display, maintaining the existing controller pattern.

Additional improvements:
- Add non_negative_decimal rule to OSPOSRules.php (leverages
  parse_decimals() for locale-aware decimal parsing)
- Preserve manual checks for business logic (return mode quantity
  exemption, discount bounds via bccomp)
- Fix PHP 8.1+ compatibility: avoid passing method return to reset()
- Explicit empty discount handling for bc-math safety

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Fix: rename to nonNegativeDecimal (PSR), clear non-English translation strings

- Rename validation rule method non_negative_decimal → nonNegativeDecimal in
  OSPOSRules.php and all $rules/$messages references in Sales.php (PSR naming
  per @objecttothis review)
- Replace English fallback text with "" in 43 non-English language files so
  CI4 falls back to the base language string; weblate will handle translations
  (per @jekkos and @objecttothis agreement)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Paul <morimori-dev@github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-04-03 14:49:42 +04:00

232 lines
14 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 [
"customers_available_points" => "Var Olan Puanlar",
"rewards_package" => "Ödüller",
"rewards_remaining_balance" => "Ödül Puanı kalan değeri ",
"account_number" => "Hesap Numarası",
"add_payment" => "Ödeme Ekle",
"amount_due" => "Kalan Ödeme",
"amount_tendered" => "Ödenen Tutar",
"authorized_signature" => "Yetkili İmza",
"cancel_sale" => "İptal Et",
"cash" => "Nakit",
"cash_1" => "",
"cash_2" => "",
"cash_3" => "",
"cash_4" => "",
"cash_adjustment" => "Nakit Düzeltimi",
"cash_deposit" => "Nakit Depozito",
"cash_filter" => "Nakit",
"change_due" => "Para Üstü",
"change_price" => "Satış Fiyatını Değiştir",
"check" => "Çek",
"check_balance" => "Çek bakiyesi",
"check_filter" => "Çek",
"close" => "",
"comment" => "Yorum",
"comments" => "Yorumlar",
"company_name" => "",
"complete" => "",
"complete_sale" => "Satışı Tamamla",
"confirm_cancel_sale" => "Bu satışı temizlemek istiyor musunuz? Tüm ürünler temizlenecek.",
"confirm_delete" => "Seçilen satışları silmek istediğinize emin misiniz?",
"confirm_restore" => "Seçilen satışları kurtarmak istediğinize emin misiniz?",
"credit" => "Kredi Kartı",
"credit_deposit" => "Kredi Depozito",
"credit_filter" => "Kredi Kartı",
"current_table" => "",
"customer" => "Müşteri",
"customer_address" => "Customer Address",
"customer_discount" => "İskonto",
"customer_email" => "E-Posta",
"customer_location" => "Konum",
"customer_mailchimp_status" => "MailChimp durumu",
"customer_optional" => "(Geciken Ödemeler İçin Gerekli)",
"customer_required" => "(Gerekli)",
"customer_total" => "Total",
"customer_total_spent" => "",
"daily_sales" => "",
"date" => "Satış Tarihi",
"date_range" => "Tarih Aralığı",
"date_required" => "Doğru tarih girilmelidir.",
"date_type" => "Tarih alanı zorunludur.",
"debit" => "Banka Kartı",
"debit_filter" => "",
"delete" => "Silmeye izin ver",
"delete_confirmation" => "Satışı silmek istediğinize emin misiniz, bu işlem geri alınamaz.",
"delete_entire_sale" => "Satışın tamamını sil",
"delete_successful" => "Satışı sildiniz.",
"delete_unsuccessful" => "Satışı silemediniz.",
"description_abbrv" => "Tanım.",
"discard" => "İptal et",
"discard_quote" => "",
"discount" => "İsko",
"discount_included" => "% İskonto",
"discount_short" => "%",
"due" => "Vade",
"due_filter" => "Vade",
"edit" => "Düzenle",
"edit_item" => "Düzenle",
"edit_sale" => "Satışı Düzenle",
"email_receipt" => "Fişi E-Postala",
"employee" => "Personel",
"entry" => "Girdi",
"error_editing_item" => "Ürün düzenleme hatası",
"negative_price_invalid" => "",
"negative_quantity_invalid" => "",
"negative_discount_invalid" => "",
"discount_percent_exceeds_100" => "",
"discount_exceeds_item_total" => "",
"negative_total_invalid" => "",
"find_or_scan_item" => "Ürün Bul/Oku",
"find_or_scan_item_or_receipt" => "Ürün yada Fiş Bul/Oku",
"giftcard" => "Hediye Çeki",
"giftcard_balance" => "Hediye Çeki Bakiyesi",
"giftcard_filter" => "",
"giftcard_number" => "Hediye Çeki No",
"group_by_category" => "Kategoriye göre gurupla",
"group_by_type" => "Tipe göre gurupla",
"hsn" => "HSN",
"id" => "Satış No",
"include_prices" => "Fiyat Dahil?",
"invoice" => "Fatura",
"invoice_confirm" => "Bu fatura şuna gönderilecek",
"invoice_enable" => "Fatura Numarası",
"invoice_filter" => "Faturalar",
"invoice_no_email" => "Bu müşterinin geçerli e-posta adresi yok.",
"invoice_number" => "Fatura #",
"invoice_number_duplicate" => "Fatura Numarası {0} eşsiz olmalıdır.",
"invoice_sent" => "Fatura gönderildi:",
"invoice_total" => "Fatura Toplamı",
"invoice_type_custom_invoice" => "Özel Fatura (custom_invoice.php)",
"invoice_type_custom_tax_invoice" => "Özel Vergi Fatura (custom_tax_invoice.php)",
"invoice_type_invoice" => "Fatura (invoice.php)",
"invoice_type_tax_invoice" => "Vergi Faturası (tax_invoice.php)",
"invoice_unsent" => "Fatura gönderilemedi",
"invoice_update" => "Yeniden Say",
"item_insufficient_of_stock" => "Ürün Stoğu Yetersiz.",
"item_name" => "Ürün Adı",
"item_number" => "Ürün No",
"item_out_of_stock" => "Ürün stokta yok.",
"key_browser" => "",
"key_cancel" => "Cancels Current Quote/Invoice/Sale",
"key_customer_search" => "Customer Search",
"key_finish_quote" => "Finish Quote/Invoice witdout payment",
"key_finish_sale" => "Add Payment and Complete Invoice/Sale",
"key_full" => "",
"key_function" => "Function",
"key_help" => "Shortcuts",
"key_help_modal" => "Open Shortcuts Window",
"key_in" => "",
"key_item_search" => "Item Search",
"key_out" => "",
"key_payment" => "Add Payment",
"key_print" => "",
"key_restore" => "",
"key_search" => "",
"key_suspend" => "Suspend Current Sale",
"key_suspended" => "Show Suspended Sales",
"key_system" => "",
"key_tendered" => "Edit Amount Tendered",
"key_title" => "Sales Keyboard Shortcuts",
"mc" => "",
"mode" => "Kayıt Kipi",
"must_enter_numeric" => "Ödenen Tutar sayı olmalıdır.",
"must_enter_numeric_giftcard" => "Hediye Çeki Numarası sayı olmalıdır.",
"new_customer" => "Yeni Müşteri",
"new_item" => "Yeni Ürün",
"no_description" => "ıklama yok",
"no_filter" => "Tümü",
"no_items_in_cart" => "Sepette ürün yok.",
"no_sales_to_display" => "Gösterilecek satış yok.",
"none_selected" => "Silinecek satış seçmediniz.",
"nontaxed_ind" => " ",
"not_authorized" => "Bu işlem için yetkisiz.",
"one_or_multiple" => "Satış(lar)",
"payment" => "Ödeme Türü",
"payment_amount" => "Tutar",
"payment_not_cover_total" => "Ödemeler toplam tutarı karşılamıyor.",
"payment_type" => "Tür",
"payments" => "",
"payments_total" => "Ödemeler Toplamı",
"price" => "Fiyat",
"print_after_sale" => "Satıştan sonra yazdır",
"quantity" => "Adet",
"quantity_less_than_reorder_level" => "Dikkat: İlgili Öge için İstenen Stok, Yeniden Düzenleme Düzeyinin altında.",
"quantity_less_than_zero" => "Dikkat: İstenen Stok yetersiz. Satışı sürdürebilirsiniz ama stoğunuzu gözden geçirin.",
"quantity_of_items" => "{0} Ögenin Miktarı",
"quote" => "Teklif",
"quote_number" => "Teklif Sayısı",
"quote_number_duplicate" => "Teklif Sayısı eşsiz olmalıdır.",
"quote_sent" => "Teklif şuna gönderildi:",
"quote_unsent" => "Teklif şuna gönderilemedi:",
"receipt" => "Satış Fişi",
"receipt_no_email" => "Müşteriye ait geçerli e-posta adresi yok.",
"receipt_number" => "Fiş #",
"receipt_sent" => "Fiş gönderildi:",
"receipt_unsent" => "Fiş gönderilemedi:",
"refund" => "Geri Ödeme Türü",
"register" => "Satış Kaydı",
"remove_customer" => "Müşteriyi Kaldır",
"remove_discount" => "",
"return" => "İade",
"rewards" => "Ödül Puanları",
"rewards_balance" => "Ödül Puanı Bakiyesi",
"sale" => "Satış",
"sale_by_invoice" => "Faturalı Satış",
"sale_for_customer" => "Müşteri:",
"sale_time" => "Saat",
"sales_tax" => "Satış Vergisi",
"sales_total" => "",
"select_customer" => "Müşteri Seç",
"send_invoice" => "Fatura Gönder",
"send_quote" => "Teklif Gönder",
"send_receipt" => "Fiş Gönder",
"send_work_order" => "İş Emri Gönder",
"serial" => "Seri",
"service_charge" => "",
"show_due" => "",
"show_invoice" => "Faturayı Göster",
"show_receipt" => "Fişi Göster",
"start_typing_customer_name" => "Müşteri ayrıntılarını yazın...",
"start_typing_item_name" => "Ürün adı yazın veya barkod taratın...",
"stock" => "Stok",
"stock_location" => "Stok yeri",
"sub_total" => "Ara Toplam",
"successfully_deleted" => "Satış başarıyla silindi",
"successfully_restored" => "Satış başarıyla kurtarıldı",
"successfully_suspended_sale" => "Satış başarıyla askıya alındı.",
"successfully_updated" => "Satış başarıyla güncellendi.",
"suspend_sale" => "Askıya Al",
"suspended_doc_id" => "Belge",
"suspended_sale_id" => "Kimlik",
"suspended_sales" => "Askıdaki Satışlar",
"table" => "Masa",
"takings" => "Günlük Satış",
"tax" => "Vergi",
"tax_id" => "Vergi Numarası",
"tax_invoice" => "Vergi Faturası",
"tax_percent" => "Vergi %",
"taxed_ind" => "V",
"total" => "Toplam",
"total_tax_exclusive" => "Vergi hariç",
"transaction_failed" => "Satış işlemi hatası.",
"unable_to_add_item" => "Ürün satışa eklenemedi",
"unsuccessfully_deleted" => "Satış silinemedi.",
"unsuccessfully_restored" => "Satış onarılamadı.",
"unsuccessfully_suspended_sale" => "Satış askıya alınamadı.",
"unsuccessfully_updated" => "Satış düzenlenemedi.",
"unsuspend" => "Satışa Al",
"unsuspend_and_delete" => "Eylem",
"update" => "Güncelle",
"upi" => "UPI",
"visa" => "",
"wholesale" => "",
"work_order" => "İş Emri",
"work_order_number" => "İş Emri Numarası",
"work_order_number_duplicate" => "İş Emri Numarası diğerinden farklı olmalı.",
"work_order_sent" => "İş Emri gönderildi:",
"work_order_unsent" => "İş Emri gönderilemedi:",
];