Commit Graph
6781 Commits
Author SHA1 Message Date
objecttothis ddf8d5df96 fix(models): use explicit SQL query to ensure atomic sort_order calculation
- Replaced query builder logic with an explicit SQL SELECT COUNT statement to calculate `sort_order` atomically within a transaction.

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-19 17:45:39 +04:00
objecttothis a7f1994404 fix(view): conditionally reload stock locations on success response
- Updated AJAX response handler to reload stock locations only when the operation is successful.

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-19 17:37:52 +04:00
objecttothis 39124e8132 fix(controllers, views): handle new stock locations in sort order and default selection
- Updated controller to resolve 'new-*' placeholders in sort order to actual IDs.
- Adjusted view logic to assign 'new-*' IDs to new stock location rows.
- Improved default selection logic to exclude new rows with unresolved IDs.

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-19 17:36:03 +04:00
objecttothis 2115fda4e5 fix(models): validate existence of stock location before setting as default
- Added check to ensure that the stock location exists and is not deleted before attempting to set it as the default.

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-19 17:17:08 +04:00
objecttothis d103790568 fix(libraries): update get_stock_destination() to allow nullable return type
Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-19 17:12:02 +04:00
objecttothis 593a2f0d7d fix(view): add aria-label for default stock location and update element IDs
- Improved accessibility by adding an `aria-label` to default stock location radio inputs.
- Updated ID formatting for stock location input elements.

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-19 17:10:08 +04:00
objecttothis a6076c9068 fix(view): use stock location-specific quantity or fallback to default
- Updated quantity input to fetch value for current stock location if available, with a fallback to the default quantity.

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-19 17:06:09 +04:00
objecttothis f18524af57 fix(view): handle undefined stock location with fallback to default
- Updated `form_count_details.php` to use the current stock location if defined, or fallback to the default.
- Ensured `display_stock` JavaScript function handles undefined stock location IDs gracefully.

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-19 17:04:25 +04:00
objecttothis f315163a18 fix(view): disable default checkbox for new stock locations and improve row selection logic
Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-19 17:01:03 +04:00
objecttothis 4f25bb540f fix(libraries): validate default location ID before assigning it in session
Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-19 16:57:41 +04:00
objecttothis 99b42f0800 fix(models): ensure dense sort_order range and clear values for deleted locations
- Simplified sort_order assignment logic to maintain dense 0..N-1 range for active locations.
- Updated deleted rows to set sort_order as NULL instead of pushing to a higher value.
- Adjusted tests and migrations to reflect the new behavior.

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-19 16:50:24 +04:00
objecttothis fa9bc0bbf3 fix(controllers): validate default stock location ID before setting it
Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-19 16:06:37 +04:00
objecttothis b14492c850 fix(view): escape dynamic stock location IDs to prevent potential XSS
Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-19 15:50:53 +04:00
objecttothis bdfcf07fe1 fix(models): handle empty location IDs in saveSortOrder method
Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-19 15:46:55 +04:00
objecttothis bd66506ce4 fix(security): escape location ID to prevent potential XSS in stock locations view
Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-19 15:45:15 +04:00
objecttothis 94adc90ee0 fix(libraries): update methods to return nullable int and handle default location assignment cautiously
Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-19 15:20:45 +04:00
Travis Garrison a8219942e2 Merge remote-tracking branch 'OpensourcePOS/master' into feature-stock-location-dropdown-order 2026-08-19 10:39:21 +04:00
objecttothis a2b91493c7 Feature: CodeIgniter Throttler (#4619)
* fix(auth): throttle login attempts to prevent brute-force attacks

Add Throttle filter and wire into login route to mitigate
credential-stuffing/brute-force risk (redacted).

- Register App\\Filters\\Throttle in Filters config
- Add \"too_many_attempts\" language string for throttled responses
- Add tests for Throttle filter and Login controller throttling

* Correct bug causing error to not display.


* i18n(login): add too_many_attempts translation for login throttling

Add localized \"too many attempts\" message across all language files
to support login throttling feature. Message informs users to wait
before retrying after exceeding attempt limit.

* fix(auth): rate limit login attempts to prevent brute-force attacks

Add Throttle filter that rate limits login/migrate POST requests,
keyed by IP and submitted username, using CodeIgniter's cache-based
Throttler (redacted).

- Wire filter into login/migrate routes
- Show localized error message when rate limit exceeded
- Broaden writable/cache ignore pattern to cover throttler cache file

* Update app/Language/ar-EG/Login.php

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* style(i18n): use single quotes for translation array keys and values

Convert double-quoted array keys and string values to single quotes
across all Login.php language files for style consistency.

* test(auth): update LoginTest to use throttler service directly

Replace clearThrottleState's Services::resetSingle('throttler') call
with Services::throttler() to reset state via the service instance.
Add usedKeys property to track throttle keys used across test cases.

* test(auth): skip login test assertion when migration required

LoginTest now check migration-required response state before
asserting HTTP 200. Prevent false failures when app force
pending-migration redirect during test run.

* Added missing return statements
2026-08-19 00:25:22 +04:00
Travis Garrison d4c295d1d8 Add unit tests for Stock_location model, covering default location handling, sort order management, and deletion behavior.
Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
2026-08-18 21:08:59 +04:00
Travis Garrison 11836c9d3a Refactor Stock_location model to adopt camelCase method naming, introduce is_default and sort_order support, add migration, UI updates, default location handling, and item synchronization.
Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
2026-08-18 20:09:52 +04:00
objecttothis 8bd2a51cb5 fix(items): validate item_number and skip receiving quantity default for temp items (#4621)
* fix(items): validate item_number and skip receiving quantity default for temp items

- Validate item_number against alpha_numeric_punct rule, return JSON error on failure
- Add item_number_invalid language string

* i18n: reorder Items language keys and add item_number_invalid string

Add item_number_invalid translation across all locale files and
resort surrounding keys alphabetically to match key ordering
convention.

* PSR-12 refactoring.

- Change local variable to camelCase.
- Use single quote in language files.

* i18n: translate item_number_invalid string in ta, th, tl, zh-Hans

Item_number_invalid key had English placeholder text in Tamil,
Thai, Tagalog, Chinese Simplified language files. Translate to
match each locale.

* fix(items): use FormatRules for item_number validation

* refactor(items): use camelCase for variable names

* refactor(items): use camelCase for variable names in Items controller
2026-08-18 02:51:42 +04:00
Sai Asish Yandobjecttothis 0e8fc0963a Reject item CSV imports whose header row is missing required columns (#4597)
* Reject item CSV imports whose header row is missing required columns

Signed-off-by: Sai Asish Y <say.apm35@gmail.com>

* Require all template columns when validating CSV import headers

Signed-off-by: Sai Asish Y <say.apm35@gmail.com>

* fix: derive required CSV import headers from the template generator

---------

Signed-off-by: Sai Asish Y <say.apm35@gmail.com>
Co-authored-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-14 14:05:43 +04:00
dependabot[bot] 65b99fea97 chore(deps): bump dompurify from 3.4.12 to 3.4.13 (#4639)
Bumps [dompurify](https://github.com/cure53/DOMPurify) from 3.4.12 to 3.4.13.
- [Release notes](https://github.com/cure53/DOMPurify/releases)
- [Commits](https://github.com/cure53/DOMPurify/compare/3.4.12...3.4.13)

---
updated-dependencies:
- dependency-name: dompurify
  dependency-version: 3.4.13
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-10 21:42:43 +04:00
dependabot[bot] 29f8f16459 chore(deps): bump codeigniter4/framework from 4.7.2 to 4.7.4 (#4638)
Bumps [codeigniter4/framework](https://github.com/codeigniter4/framework) from 4.7.2 to 4.7.4.
- [Release notes](https://github.com/codeigniter4/framework/releases)
- [Commits](https://github.com/codeigniter4/framework/compare/v4.7.2...v4.7.4)

---
updated-dependencies:
- dependency-name: codeigniter4/framework
  dependency-version: 4.7.4
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-09 19:58:14 +02:00
objecttothisandTravis Garrison 5c9b1b81e6 fix(xss): remove redundant escaping that double-encoded item attribute values (#4628)
* fix(xss): remove redundant escaping that double-encoded item attribute values

- Remove esc()/html_entity_decode() calls now that output is escaped
  at render time by the framework, preventing double-encoding of
  special characters in attribute names, units, and definition values
- Fix employee_name form_input value fields to stop pre-escaping
  before form_input applies its own escaping
- Reorder Items.php use statements and add missing BaseConnection import
- Change items/manage.php start_date from let to plain assignment for
  proper reassignment scope

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>

* test(sales): add regression tests for permission checks on sales endpoints

- Ensure role-based permissions correctly restrict access to sensitive actions like price edits, receipt/invoice views, and report generation.
- Add tests for both granted and restricted user scenarios to validate the behavior.

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>

* fix(attributes): validate `attribute_value` before processing

- Add checks to ensure `attribute_value` is a non-empty string in `postSaveAttributeValue` and `postDeleteDropdownAttributeValue` methods.
- Return error response if validation fails to prevent invalid data handling.

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>

* fix(attributes): improve error handling and optimize affected items processing

- Use `array_column` for extracting item IDs to streamline logic.
- Add JSON validation with `JSON_THROW_ON_ERROR` and return proper error response for invalid `definition_values`.

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>

* test(sales): enable database refresh for consistent test state

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>

* test(sales): assert unauthorized message is displayed on restricted access

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>

* refactor(attributes): use camelCase for `attributeValue` in controller methods

- Standardize variable naming in `postSaveAttributeValue` and `postDeleteDropdownAttributeValue` methods by switching to camelCase.

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>

---------

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
Co-authored-by: Travis Garrison <travis@chiraqbookstore.com>
2026-08-09 11:37:38 +04:00
richardmilles 08b0951a84 fix: use db_connect() for item save transactions (#4636)
postSave() called $this->db which is not set on the Items controller, causing Undefined property errors when saving items. Match the CSV import path and obtain the connection via db_connect().

Fixes #4623
2026-08-09 00:10:53 +02:00
objecttothisandTravis Garrison f5ba1709eb fix(security): sanitize filenames and escape logo path in config (#4630)
* fix(security): sanitize filenames and escape logo path in config

- Sanitize uploaded filename in Config.php via preg_replace, strip
  chars outside [a-zA-Z0-9_-] before storing raw_name
- Escape $logo_src with esc(..., 'attr') in info_config.php view to
  prevent XSS via crafted logo path/filename

Prevents stored XSS and path traversal from unsanitized filenames
used in config uploads.

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>

* fix(config): sanitize uploaded config filenames

Replace inline regex filename sanitization with sanitize_filename()
helper to prevent path traversal via crafted upload filenames.

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>

---------

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
Co-authored-by: Travis Garrison <travis@chiraqbookstore.com>
2026-08-07 20:30:02 +04:00
Rayan Abdul Caderandobjecttothis aa96ad0284 refactor: apply PSR-12 naming to Attribute definition methods (#4624)
Renames the Attribute-specific definition methods from snake_case to
camelCase and updates every call site:

  get_definition_by_name   -> getDefinitionByName
  get_definition_names     -> getDefinitionNames
  get_definition_values    -> getDefinitionValues
  get_definitions_by_type  -> getDefinitionsByType
  get_definitions_by_flags -> getDefinitionsByFlags
  get_definition_flags     -> getDefinitionFlags

Also documents getDefinitionByName()'s return contract: a single
definition row as an associative array, or [] when none matches,
matching the getRowArray() behaviour introduced in #4464.

get_found_rows() and get_total_rows() are deliberately left alone -
they are declared across 15 models and renaming them only here would
break that shared convention.

Refs #4622

Co-authored-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-07 13:13:05 +04:00
objecttothisandTravis Garrison a5d70c07bb fix(auth): validate gcaptcha before password to prevent bypass (#4618)
* fix(auth): validate gcaptcha before password to prevent bypass

Move gcaptcha check before credential validation so a valid captcha
is required prior to any login attempt. Previously, password auth
ran first, allowing timing-based enumeration without captcha.

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>

* test(auth): add regression tests for gcaptcha validation order in OSPOSRules

Guards fix from 5dea748b0: gcaptcha must be validated before
Employee::login() is attempted to prevent auth bypass.

Change gcaptcha_check visibility to protected to allow testing.

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>

---------

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
Co-authored-by: Travis Garrison <travis@chiraqbookstore.com>
2026-08-07 02:27:33 +04:00
objecttothisandTravis Garrison 35f056ce69 refactor(migrations): rename execute_script to executeScript across all migrations (#4611)
Align migration helper function calls with PSR-12 camelCase naming convention.
Affects all migration files from initial schema through recent upgrades.

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
Co-authored-by: Travis Garrison <travis@chiraqbookstore.com>
2026-08-07 02:26:43 +04:00
objecttothisandTravis Garrison 0808ffae0d fix(sales): escape quote number in email template to prevent XSS (#4625)
Wrap $quote_number output with esc() in quote_email.php. Raw
interpolation allowed injected HTML/JS via quote number field.

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
Co-authored-by: Travis Garrison <travis@chiraqbookstore.com>
2026-08-07 02:21:19 +04:00
objecttothisandTravis Garrison 3bafa07e04 fix(sales): enforce server-side authorization for price changes (#4631)
Client-side \"change_price\" flag is UI-only, not trustworthy. Compare
submitted price against current cart price server-side and require
sales_change_price grant when they differ, else reject with
not_authorized error.

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
Co-authored-by: Travis Garrison <travis@chiraqbookstore.com>
2026-08-07 02:20:01 +04:00
2c69dc0c34 fix(config): validate theme param to prevent XSS via invalid theme (#4620)
* fix(config): validate theme param to prevent XSS via invalid theme

Add validation rule for theme field before batch save, rejecting
requests with unrecognized theme values. Add test coverage for
theme validation in postSaveGeneral.

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>

* Update app/Config/Validation/OSPOSRules.php

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

---------

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
Co-authored-by: Travis Garrison <travis@chiraqbookstore.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-08-07 02:18:44 +04:00
0a4c418690 fix: get_definition_by_name() returns single row instead of multi-dimensional array (#4452) (#4464)
Co-authored-by: jekkos <jekkos@users.noreply.github.com>
Co-authored-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-06 12:27:13 +04:00
6e273a2fb1 refactor: Replace var with let/const in JavaScript files (#4503)
* refactor: Replace var with let/const in JavaScript files

- Replace var with let for variables that are reassigned
- Replace var with const for variables that are never reassigned
- Modernize manage_tables.js and nominatim.autocomplete.js
- Skip third-party libraries (imgpreview.full.jquery.js, clipboard.min.js)

Closes #4491

* refactor: Replace var with let/const in inline JavaScript

- Fixed CodeRabbit review: changed enable_actions and load_success
  from const to let in manage_tables.js (they are reassigned in init)
- Replaced all var declarations in inline JavaScript in Views with
  let (for reassigned) or const (for never reassigned)
- Modernized 48 additional files with inline JavaScript

* refactor: Replace var with let/const in remaining JS files

- Modernized gulpfile.js: 3 var declarations replaced
- Modernized app/Views/errors/html/debug.js: all var declarations replaced
- Used const for never-reassigned, let for reassigned variables

* fix: Replace remaining var declarations in Views

- Changed var  to const in sales/register.php
- Changed var  to const in configs/receipt_config.php

These were missed in the initial pass.

* fix: Replace remaining var declarations in gulpfile.js

- Converted 12 remaining var declarations to const
- All variables are function-scoped and never reassigned
- Complete coverage for this file now

* fix: Address CodeRabbit review comments

- items/manage.php: Remove duplicate let declaration for start_date
  (partial/daterangepicker already declares it)
- header_js.php: Escape CSRF hash in JavaScript context
- tax_jurisdictions.php: Fix mismatched selector (remove_tax_jurisdictions
  -> remove_tax_jurisdiction)

* style(views): Replace var with let/const and fix comment casing

- Convert var to let in items/manage.php for JS modernization
- Capitalize \"Submit\" in validation comments across tax view files

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>

---------

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
Co-authored-by: Ollama <ollama@steganos.dev>
Co-authored-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
Co-authored-by: Travis Garrison <travis@chiraqbookstore.com>
2026-08-06 12:15:45 +04:00
c0abf80c86 fix: Wrap postSave() in single transaction for atomicity (#4506)
* fix: wrap postSave() in single transaction for atomicity

- Remove internal transaction from Item_taxes->save_value() to allow controller-level transaction
- Wrap entire save sequence (item, taxes, quantities, inventory, attributes) in single transaction
- Ensure all operations succeed or all fail together
- Prevents partial writes when saveItemAttributes() fails after item/tax/quantity saves succeed

Fixes #4474

* fix: Use explicit transBegin/transCommit/transRollback for atomicity

- Replace transStart/transComplete with transBegin/transCommit/transRollback
- Check all success conditions before committing
- Explicit rollback on failure

Address CodeRabbit review feedback

* refactor(items): rename postSave locals to camelCase per PSR-12

Convert snake_case variables to camelCase in postSave() and related
item-save logic to match project naming convention for new methods.

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>

---------

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
Co-authored-by: Ollama <ollama@steganos.dev>
Co-authored-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
Co-authored-by: Travis Garrison <travis@chiraqbookstore.com>
2026-08-06 12:04:16 +04:00
cdf477f823 fix(login): skip auth validation on new install to allow migration (#4609)
* fix(login): skip auth validation on new install to allow migration

On fresh installs with no DB version, login validation would fail
before migrations could run. Check MY_Migration::getCurrentVersion()
and bypass credential check when no version exists.

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>

* fix(login): distinguish DB unavailable from empty install

`getCurrentVersion()` previously returned `int` with 0 used for both
\"empty database\" and \"DB connection failure\". This conflated two
distinct states, causing login to skip auth when DB was unreachable.

Changes:
- Return type widened to `?int`: null = DB unavailable, 0 = confirmed
  empty DB (new install), positive int = migrated
- Login controller now returns 503 on null (DB error) before checking
  isNewInstall
- isNewInstall gate now uses `=== 0` instead of falsy check

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>

* fix(login): return 503 JSON response when DB connection unavailable

Extract getCurrentVersion() before building data array to distinguish
null (connection failure) from 0 (new install). Return early with JSON
503 when DB is unreachable instead of rendering broken view.

Update return type hint to include ResponseInterface.

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>

---------

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
Co-authored-by: Travis Garrison <travis@chiraqbookstore.com>
Co-authored-by: jekkos <jekkos@users.noreply.github.com>
2026-08-05 11:48:05 +04:00
objecttothisandTravis Garrison 8e465f9256 chore(deps): bump lodash.template from 4.5.0 to 4.18.1 (#4616)
Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
Co-authored-by: Travis Garrison <travis@chiraqbookstore.com>
2026-08-04 17:58:50 +04:00
objecttothisandTravis Garrison 734c7d291c chore(deps): add xlsx via SheetJS CDN and upgrade tableexport plugin (#4615)
- Add xlsx 0.20.3 from SheetJS CDN via package overrides
- Bump tableexport.jquery.plugin from ^1.30.0 to ^1.33.0
- Add xlsx bundle to gulp JS pipeline before tableexport

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
Co-authored-by: Travis Garrison <travis@chiraqbookstore.com>
2026-08-04 17:57:41 +04:00
dependabot[bot] 337cc098f2 chore(deps): bump brace-expansion (#4614)
Bumps  and [brace-expansion](https://github.com/juliangruber/brace-expansion). These dependencies needed to be updated together.

Updates `brace-expansion` from 1.1.12 to 1.1.18
- [Release notes](https://github.com/juliangruber/brace-expansion/releases)
- [Commits](https://github.com/juliangruber/brace-expansion/compare/v1.1.12...v1.1.18)

Updates `brace-expansion` from 2.1.0 to 2.1.4
- [Release notes](https://github.com/juliangruber/brace-expansion/releases)
- [Commits](https://github.com/juliangruber/brace-expansion/compare/v1.1.12...v1.1.18)

---
updated-dependencies:
- dependency-name: brace-expansion
  dependency-version: 1.1.18
  dependency-type: indirect
- dependency-name: brace-expansion
  dependency-version: 2.1.4
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-04 17:15:13 +04:00
objecttothisandTravis Garrison 89677cb8f2 chore(deps): upgrade dompdf from v2.0.8 to v3.1.6 (#4610)
- Update dompdf/dompdf constraint from ^2.0.3 to ^3.1.6
- Dependency names changed: phenx/php-font-lib and phenx/php-svg-lib
  replaced by dompdf/php-font-lib and dompdf/php-svg-lib ^1.0.0
- Remove ThirdParty/dompdf path from Autoload.php psr4 namespace map
- Update composer.lock with new content hash and package references

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
Co-authored-by: Travis Garrison <travis@chiraqbookstore.com>
2026-08-01 00:24:02 +02:00
objecttothisandTravis Garrison 2fbe746c95 style(models): normalize quote style in SQL GROUP_CONCAT expression (#4608)
Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
Co-authored-by: Travis Garrison <travis@chiraqbookstore.com>
2026-07-30 15:21:29 +04:00
objecttothisandTravis Garrison 231e716c14 bugfix(reports): crash on detailed sales report when sale has multiple payments with reference codes (#4599)
* fix(sales): aggregate reference codes for multi-payment sales

Use GROUP_CONCAT to combine multiple payment reference codes into a
single comma-separated value, and group only by sale_id to correctly
handle sales with multiple payment records.

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>

* docs(agents): update AGENTS.md with expanded coding standards

- Clarify PSR-12 enforcement via PHP-CS-Fixer config reference
- Bump minimum PHP version requirement from 8.1 to 8.2
- Add JavaScript const/let/var convention rule
- Reorganize coding standards section for clarity

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>

* fix(sales): exclude empty strings from payment reference code aggregation

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>

---------

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
Co-authored-by: Travis Garrison <travis@chiraqbookstore.com>
2026-07-28 14:23:54 +04:00
dependabot[bot] 0107524f71 chore(deps): bump dompurify from 3.4.11 to 3.4.12 (#4602)
Bumps [dompurify](https://github.com/cure53/DOMPurify) from 3.4.11 to 3.4.12.
- [Release notes](https://github.com/cure53/DOMPurify/releases)
- [Commits](https://github.com/cure53/DOMPurify/compare/3.4.11...3.4.12)

---
updated-dependencies:
- dependency-name: dompurify
  dependency-version: 3.4.12
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-28 14:22:36 +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
objecttothisandTravis Garrison 9c542efaf6 Feature: Payment reference code (#4587)
* 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>
2026-07-10 13:49:05 +04:00
objecttothisandTravis Garrison b4b22863be Forgotten commit from login migration branch (#4592)
- suppress JSInitializingVariableWithUndefined inspection warning
- Add checks to not require username/password when isNewInstall is true

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
Co-authored-by: Travis Garrison <travis@chiraqbookstore.com>
2026-07-07 13:20:46 +04:00
objecttothisandTravis Garrison dec736ad6c Bugfix: Fix problems with migration UI in login (#4589)
* refactor(login): rename methods and keys to camelCase, add initialization keys

- Rename snake_case methods to camelCase in MY_Migration and callers:
  is_latest() → isLatest(), migrate_to_ci4() → migrateToCI4(),
  get_latest_migration() → getLatestMigration(),
  get_current_version() → getCurrentVersion()
- Rename snake_case array keys to camelCase in Login controller:
  has_errors → hasErrors, is_new_install → isNewInstall,
  is_latest → isLatest, latest_version → latestVersion,
  gcaptcha_enabled → gcaptchaEnabled
- Add initialization_required, initialization_message, initialize keys
  to all language files to support new install flow messaging

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>

* refactor(login): move auth validation before migration, reorder language keys alphabetically

- Validate credentials with login_check rule before attempting migration
- Return 401 with invalid credentials message on validation failure
- Alphabetically reorder and align language file keys across all locales
- Add new migration status keys: migrating_database, migration_complete,
  migration_complete_login, migration_complete_migrate
- Remove deprecated keys: migration_needed, migration_initializing,
  migration_running, migration_required

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>

---------

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
Co-authored-by: Travis Garrison <travis@chiraqbookstore.com>
2026-07-07 10:35:25 +04:00
dependabot[bot]andobjecttothis 632d4eacce chore(deps): bump dompurify from 3.4.0 to 3.4.11 (#4578)
Bumps [dompurify](https://github.com/cure53/DOMPurify) from 3.4.0 to 3.4.11.
- [Release notes](https://github.com/cure53/DOMPurify/releases)
- [Commits](https://github.com/cure53/DOMPurify/compare/3.4.0...3.4.11)

---
updated-dependencies:
- dependency-name: dompurify
  dependency-version: 3.4.11
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-06-26 16:45:30 +04:00
jekkos 6342d4513a fix(security): Escape attribute value in register 2026-06-19 22:12:29 +02:00