Commit Graph
15 Commits
Author SHA1 Message Date
jekkosandobjecttothis 839821e2eb bugfix(sales): reject non-negative gift-card amount_tendered (#4674)
* Validate gift-card payment amounts (GHSA-9847)

Close the negative gift-card amount minting vector: when a forged
payment_type like 'Gift Card:<number>' reaches the catch-all validation
branch, a negative amount_tendered previously passed decimal_locale and was
then routed into Giftcard::decrementGiftcardValue, where value - (-N)
increased the balance (store credit minted at will).

- Add nonNegativeDecimal rule + 'Sales.negative_amount_tendered' message to
  the catch-all amount_tendered rules in Sales::postAddPayment(); add the
  language key to all 46 locale files (populated in en, empty elsewhere).
- Guard Giftcard::decrementGiftcardValue() against non-positive amounts so
  the sink itself can no longer add balance from an inverted subtraction.
- Regression tests: controller-level rejection of negative amount_tendered
  and model-level rejection of negative/zero decrements.

* Address PR review: align locale keys, drop advisory refs, add decimal_locale message

- Align negative_amount_tendered '=> with all other keys (46 locale files)
- Remove docblock + inline comment above decrementGiftcardValue()
- Remove GHSA ID and attack-detail description from test; scrub redundant comment
- Add decimal_locale message override + focused malformed-amount test

* Fix formatting and spacing in SalesControllerTest

* fix(lang): remove duplicate negative amount tendered key

Consolidate 'negative_amount_invalid' and 'negative_amount_tendered'
translation keys in Sales.php across all locale files. Both keys held
identical messages, causing redundant translation maintenance.

- Drop 'negative_amount_invalid' key, keep 'negative_amount_tendered'
- Move existing translated text into 'negative_amount_tendered' where
  it was previously empty
- Applied across all app/Language/*/Sales.php locale files

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>

* fix(sales): allow negative amount_tendered in return mode

Return transactions legitimately produce negative amount_due and
prefilled amount_tendered values, but validation rules previously
enforced nonNegativeDecimal unconditionally, blocking valid returns.

- Detect return mode via sale_lib->get_mode() in Sales::process
- Build amount_tendered rule conditionally: skip nonNegativeDecimal
  check when in return mode, keep it for sale/giftcard flows
- Apply the conditional rule to both giftcard and standard payment
  branches

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>

* test: update expected error message in negative payment test

Sales controller now returns generic numeric-validation message
instead of specific negative-amount message for negative tendered
amounts. Update test assertion to match new lang key.

- tests/Controllers/SalesControllerTest.php: assert
  Sales.must_enter_numeric instead of
  Sales.negative_amount_tendered

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>

* test: remove regression tests for GHSA-9847 negative amount fix

Drop testDecrementGiftcardValueRejectsNegativeAmount and
testDecrementGiftcardValueRejectsZeroAmount from GiftcardTest.

- Remove coverage for decrementGiftcardValue() rejecting
  non-positive amounts (negative/zero) in tests/Models/GiftcardTest.php

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>

---------

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
Co-authored-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-09-07 11:47:02 +04:00
objecttothis f5f9052de1 fix(sales): harden payment validation and gift card handling
- Validate paymentType is a non-empty string before processing
- Reject negative or zero amounts for all payment types
- Enforce full payment coverage before completing a sale
- Bypass coverage check for invoice and quote mode sales
- Require a valid gift card number before decrementing value;
  rollback and return insufficient balance error on missing input
- Add "amount_due_not_covered" and "negative_amount_invalid"
  translations across 40+ locales
- Add test coverage for gift card validation, negative amounts,
  and quote/invoice zero-payment completion
- Rename snake_case locals to camelCase in postComplete (no behavior change)
2026-09-02 01:21:46 +04:00
objecttothis 29a9b1a7e7 Bugfix: Resolve Race Condition in Rewards and Gift Card Spending (#4640)
* Implement atomic updates for gift card and reward point decrements, enhance error handling for insufficient balances, and add regression tests for concurrency safety.

* Add translations for insufficient gift card balance and reward points error messages across all supported languages.

* Reorder `clear_suspended_sale_detail` call to ensure transactional consistency.

* Reorder `clear_all` call to align with success and error handling logic.

* Ensure soft-deleted gift cards are excluded in balance updates.

* Refactor change_quantity logic with atomic upserts, improve error handling for insufficient stock, and update related tests and constants.

* Added check for NEW_ENTRY

* Added unit tests to test changes.

* Fix class name casing in ItemQuantityTest for consistency.

* Fix Bulgarian translations for insufficient balance error messages in Sales module.

* Fix Greek translations for insufficient balance error messages in Sales module.

* Fix Armenian translations for insufficient balance error messages in Sales module.

* Fix Tamil translations for insufficient balance error messages in Sales module.

* Implement race condition testing for database methods with concurrent process support.

* Fix class name casing in ItemTest for consistency.

* Improve concurrent process handling in race condition tests; add readiness and synchronization barriers.

* Improve handling of process I/O streams and timeout management in race condition tests.

* Add test for decrementing gift card value when marked as deleted

* Add `finally` block to ensure proper cleanup in async database race condition tests

* Improve error handling and timeout management in async database race condition tests.

* Refactor test utilities to use shared `EmployeeFixtureTrait` and `ItemFixtureTrait`.

* Track process exit codes explicitly in race condition tests for improved error detection and debugging.

* Improve error handling in `ConcurrentDbRaceTrait` by adding exceptions for `mysqli_poll` and `mysqli_reap_async_query`.

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>

---------

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-20 02:24:23 +04:00
objecttothisandTravis Garrison eb4c3d8764 fix(giftcard): correct return type and rename getGiftcardId method (#4600)
- Rename get_giftcard_id to getGiftcardId (PSR-12 camelCase)
- Fix return type from bool to int|false
- Replace loose == with strict === comparison
- Update all call sites in Giftcards controller and Sale model

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
Co-authored-by: Travis Garrison <travis@chiraqbookstore.com>
2026-07-24 01:46:52 +04:00
jekkos 46e31b1c16 Allow anonymous giftcard creation (#4278)
* Allow giftcard without person (#4276)

* Update giftcard form validation (#4276)
2025-11-24 22:54:52 +01:00
BudsieBuds e83c23cf0c Improve code style and PSR-12 compliance (#4204)
* 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
2025-05-02 19:37:06 +02:00
objecttothis e90b5b87da Replace tabs with spaces (#4196)
Signed-off-by: objecttothis <objecttothis@gmail.com>
2025-03-28 21:24:21 +04:00
jekkos eeaa693ede Fix for giftcard numbering (#4182) 2025-02-15 01:12:35 +01:00
jekkosandobjecttothis f49d763254 XSS mitigation features (#4041)
* Remove HtmlPurifier calls

- All calls to Services::htmlPurifier()->purify() removed from data received from view.
- Bootstrap and bootswatch bump in package-lock.json

Signed-off-by: objecttothis <objecttothis@gmail.com>

* Pre-view filtering Items Controller

- Refactored code for clarity
- Created and called sanitization functions.
- Sanitize TEXT type Attributes before being sent to the view.

Signed-off-by: objecttothis <objecttothis@gmail.com>

* Pre-view filtering Customers Controller

- Refactored code for clarity
- Replaced == with === operator to prevent type juggling
- Added Sanitization of Customer data before being sent to the view

Signed-off-by: objecttothis <objecttothis@gmail.com>

* Bump bootstrap-table to 1.23.1

- Bump bootstrap-table to 1.23.1 in attempt to resolve issue with sticky headers
- Sanitize attribute data in tables
- Sanitize item data with controller function.

Signed-off-by: objecttothis <objecttothis@gmail.com>

* Pre-view filtering Items Controller

- Refactored code for clarity
- Created and called sanitization functions.
- Sanitize TEXT type Attributes before being sent to the view.

Signed-off-by: objecttothis <objecttothis@gmail.com>

* Sanitize Item data

- Sanitize category and item_number before display in forms.
- refactor check in pic_filename for empty to be best practices compliant.
- Added TODO

Signed-off-by: objecttothis <objecttothis@gmail.com>

* Minor changes

- Refactored for code clarity.
- Removed extra blank lines.
- Minor reformatting.
- Added PHPdocs
- bumped bootstrap-table to 1.23.2

Signed-off-by: objecttothis <objecttothis@gmail.com>

* Pre-view filtering Items Controller

- Refactored code for clarity
- Created and called sanitization functions.
- Sanitize TEXT type Attributes before being sent to the view.

Signed-off-by: objecttothis <objecttothis@gmail.com>

* Sanitize Item data

- Sanitize category and item_number before display in forms.
- refactor check in pic_filename for empty to be best practices compliant.
- Added TODO

Signed-off-by: objecttothis <objecttothis@gmail.com>

---------

Signed-off-by: objecttothis <objecttothis@gmail.com>
Co-authored-by: objecttothis <objecttothis@gmail.com>
2024-08-26 11:35:56 +04:00
objecttothis e71c035671 Formatting
- Made view CI form helper function call format uniform.
- replaced calls to array() with []
- Placed { on its own line
- Removed empty lines where there shouldn't be any.
- Replaced text/javascript with application/javascript as the former is deprecated
2024-06-15 17:19:15 +02:00
objecttothis 7b224be665 PSR compliance and formatting changes
- Replaced TRUE/FALSE constants with true/false keywords
- Replaced NULL constant with null keyword
- Replaced `<?php echo` in views with shortened `<?=`
- Added missing variable declaration
- Added missing function return type in declaration
- replaced `== true`, `== false`, `=== true` and `=== false` in if statements with simplified forms
2024-06-15 17:19:15 +02:00
Steve Ireland 4798041408 Tack on the void return type onto the Employee:logout method. 2024-06-15 17:19:15 +02:00
objecttothis ae357cab4a Formatting
- Convert indents to tabs
- Remove unnecessary else statement
- Correct PHPDoc formatting
2024-06-15 17:19:15 +02:00
objecttothis f84b795ee6 Upgrade to CodeIgniter 4.1.3 2024-06-15 17:19:15 +02:00
jekkos 73b189b6d4 Prepare rebase: move files to new folder structure 2024-06-15 17:19:15 +02:00