* Add `reference_code` to sale payment queries and group by statements
Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
* Refactor `Sales` controller to improve payment handling readability and replace snake_case with camelCase variables
Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
* Add missing translations for `Sales` language file and include new keys like `must_enter_rrn` and `reference_code`
Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
* Refactor `Sales` payment handling to use camelCase and extend `addPayment` with `referenceCode` support
Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
* Refactor `Sales` models, controllers, and libraries to adopt camelCase naming conventions and improve readability
Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
* Add translations and updates for `must_enter_reference_code` and `reference_code` across language files and update `Sales` controller to replace `must_enter_rrn` with the new key
Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
* feat(sales): add reference code input and payment type helper
- Add `get_reference_code_payment_types()` to locale_helper as single
source of truth for card-requiring payment types
- Add reference code row to register view, shown/hidden via JS based
on selected payment type
- Fix payment type dropdown width to 100% for consistent layout
- Add min-width to payment buttons and right-padding to button group
Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
* feat(config): add payment reference code length configuration
- Add payment_reference_code_min and payment_reference_code_max fields
to Config controller save logic
- Add translation keys for reference code length limits across all
language files (min/max label + section header)
- Align array key formatting in Config controller for readability
Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
* style(lang): normalize string delimiters to single quotes across all language files
Convert double-quoted array keys and values to single quotes in all
app/Language/*/Config.php and app/Language/*/Sales.php variants.
No translation content changed — formatting only.
Also add Localization section to AGENTS.md documenting language file
conventions for new keys and fallback behavior.
Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
* feat(lang): add payment reference code length translations
Add localized strings for payment_reference_code_length_limits,
payment_reference_code_length_max_label, and
payment_reference_code_length_min_label across all supported locales.
Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
* test(config,sales): add payment reference code min/max validation tests
- Add baseLocalePayload() helper in ConfigTest for postSaveLocale tests
- Add testSaveLocale_AcceptsValidReferenceCodeMinMax and related boundary tests
- Add Sale_libPaymentTest for payment reference code validation in Sale_lib
Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
* fix(sales): add type-specific validation for amount_tendered
Gift card payments use amount_tendered as giftcard number (integer);
cash/other payments require decimal_locale format. Apply correct
validation rule per payment type instead of generic required.
Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
* fix(lang): replace self-closing </br> with <br> in all locales
Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
* fix(sales): use configurable precision in discount comparison
Replace hardcoded precision 2 with totals_decimals() when comparing
discount against item total via bccomp/bcmul, so discount validation
respects the configured decimal precision setting.
Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
* fix(lang): correct Azerbaijani translations in Config.php
Replace placeholder/mismatched strings with accurate translations:
- email_mailpath, email_smtp_pass, invoice_email_message
- number_locale_invalid/required, receipt_template
- reward_configuration, right, tax_decimals, theme
Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
* feat(sales): add reference code support to payment edit flow
- Add reference_code field to new payment row in sale edit form
- Persist reference_code on insert in Sale model
- Validate reference_code_new in Sales controller using configurable min/max length rules
Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
* feat(lang): add Georgian (ka) language stubs for Config and Sales
Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
* Match the fallback maximum reference_code length to the maximum of the field in the db
Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
* Bug fixes
- Add validation of UI settings to prevent overridden values from being passed.
- Correct maximum value in JS for payment_reference_code maximum length to 40.
- Fix bug causing copy_entire_sale() to incorrectly copy the reference code and cash_adjustment
Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
---------
Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
Co-authored-by: Travis Garrison <travis@chiraqbookstore.com>
The check_encryption() function now properly handles Docker/container
environments where ROOTPATH/.env may be read-only or ephemeral.
Changes:
- Returns false when key persistence fails instead of always returning true
- Removes error suppression (@) to properly detect write failures
- Adds fallback to WRITEPATH/config/encryption.key for container volumes
- Splits logic into separate functions for clarity and testability
Fixes encryption key being lost on container restarts, which caused
stored passwords to become undecryptable.
GitHub-Issue: #4554
Add fallback key loading from WRITEPATH in Encryption config
When encryption key is not available from .env or environment variables,
the config now attempts to load from WRITEPATH/config/encryption.key.
This supports Docker environments where:
- .env file is read-only or ephemeral
- Key was persisted to the writable volume via check_encryption()
GitHub-Issue: #4554
Handle encryption unavailability gracefully in controllers
Changed EncrypterInterface property to nullable and added proper error
handling for cases where encryption key is not available.
Changes:
- Config controller: nullable encrypter property, try/catch around encryption
- Email_lib: check encryption before using encrypter
- Return meaningful error messages when encryption fails
- Log warnings when passwords saved without encryption
Users will now see clear error messages instead of unhandled exceptions
when encryption key cannot be initialized.
GitHub-Issue: #4554
Add encryption_failed error message to language file
Added localization string for encryption failure error messages.
GitHub-Issue: #4554
Add decrypt_value() and encrypt_value() helper functions
Extracts the recurring decryption/encryption pattern into reusable helper
functions with consistent error handling:
- decrypt_value(): Safely decrypts encrypted values with try/catch
- encrypt_value(): Safely encrypts values with error handling
Both functions handle:
- Empty/null values gracefully
- Missing encryption key (logs warning)
- Encryption/decryption failures (logs error, returns default)
This pattern appears in 8+ locations across the codebase.
GitHub-Issue: #4554
Refactor all encryption/decryption to use helper functions
Replaces direct encrypter calls with decrypt_value() and encrypt_value()
helpers throughout the codebase for consistent error handling:
- Config controller: SMTP, SMS, Mailchimp credential encryption
- Email_lib: SMTP password decryption
- Sms_lib: SMS password decryption
- Mailchimp_lib: API key decryption
- Customers controller: Mailchimp list ID decryption
Removes nullable EncrypterInterface property from Config controller as
encryption is now handled via helper functions.
GitHub-Issue: #4554
Address CodeRabbit feedback: validate key length, clarify encryption failure handling
- loadKeyFromWritable() now validates key length >= 64 before accepting
- encrypt_value() renamed param, defaults to failing encryption required
- Clearer error message when credentials not saved
GitHub-Issue: #4554
fix: address CodeRabbit review comments for encryption key persistence
- Always mirror encryption key to both .env and WRITEPATH (Docker safety)
- Guard array key access with isset() before reading in Encryption.php
- Fix encrypt_value() to not treat string '0' as empty
- Improve error logging for failed encryption attempts
refactor: PSR-compliant naming and address objecttothis review comments
- Rename functions to camelCase: checkEncryption, writeEncryptionKeyToEnv, writeEncryptionKeyToWritable, loadEncryptionKeyFromWritable, abortEncryptionConversion, removeBackup, decryptValue, encryptValue
- Update all callers in Config.php, Customers.php, Migrations, Email_lib.php, Sms_lib.php, Mailchimp_lib.php
- Add EncryptionException import in security_helper.php (removed FQN)
- Use camelCase variables: $smtpPass, $emailConfig, $batchSaveData in affected files
- Remove unnecessary inline comments (code is self-documenting)
- Keep necessary docstrings for public API documentation
Address remaining CodeRabbit review comments
- Fix decryptValue() to use explicit null/empty check instead of empty()
(handles string "0" correctly)
- Guard checkEncryption() result in migration before proceeding
- Check read success before writing backup restoration
- Consistent DIRECTORY_SEPARATOR usage in paths
GitHub-Issue: #4554
Add validation for the mailpath POST parameter to prevent command injection
attacks. The path is validated to only allow alphanumeric characters,
underscores, dashes, forward slashes, and dots.
- Required mailpath when protocol is "sendmail"
- Validates format for all non-empty mailpath values
- Blocks common injection vectors: ; | & ` $() spaces newlines
- Added mailpath_invalid translation to all 43 language files
- Simplified validation logic to avoid redundant conditions
Files changed:
- app/Controllers/Config.php: Add regex validation with protocol check
- app/Language/*/Config.php: Add mailpath_invalid error message (43 languages)
- tests/Controllers/ConfigTest.php: Unit tests for validation
* Improve code style and PSR-12 compliance
- refactored code formatting to adhere to PSR-12 guidelines
- standardized coding conventions across the codebase
- added missing framework files and reverted markup changes
- reformatted arrays for enhanced readability
- updated language files for consistent styling and clarity
- minor miscellaneous improvements