Files
opensourcepos/app/Events/Db_log.php
objecttothis 577cf55b6a [Feature]: Case-sensitive attribute updates and CSV Import attribute deletion capability (#4384)
PSR and Readability Changes
- Removed unused import
- Corrected PHPdoc to include the correct return type
- Refactored out a function to get attribute data from the row in a CSV item import.
- refactored snake_case variables and function names to camelCase
- Refactored the naming of saveAttributeData() to better reflect the functions purpose.
- Improved PHPdocs
- Remove whitespace
- Remove unneeded comment
- Refactored abbreviated variable name for clarity
- Removed $csvHeaders as it is unused
- Corrected spacing and curly brace location
- Refactored Stock Locations validation inside general validation

Bugfixes
- Fixed bug causing attribute_id and item_id to not be properly assigned when empty() returns true.
- Fixed bug causing CSV Item import to not update barcode when changed in the import file.
- Fixed saveAttributeValue() logic causing attribute_value to be updated to a value that already exists for a different attribute_id
- Fixed bug preventing Category as dropdown functionality from working
- Fixed bug preventing barcodes from updating. in Item CSV Imports
- Corrected bug in stock_location->save_value()
- Corrected incorrect helper file references.
- Removed duplicate call to save attribute link
- Rollback transaction on failure before returning false
- Rollback transaction and return 0 on failure to save attribute link.
- Account for '0' being an acceptable TEXT or DECIMAL attributeValue.
- Corrected Business logic
- Resolved incorrect array key
- Account for 0 in column values
- Correct check empty attribute check
- Previously 0 would have been skipped even though that's a valid value for an attribute.
- Removed unused foreach loop index variables
- Corrected CodeIgniter Framework version to specific version

UnitTest Seeder and tests
- Created a seeder to automatically prepare the test database.
- Modified the Unit Test setup to properly seed the test database.
- Wrote a unit test to test deleting an attribute from an item through the CSV.
- Corrected errors in unit tests preventing them from passing. save_value() returns a bool, not the itemId
- Fix Unit Tests that were failing
- Corrected the logic in itemUpdate test
- Replaced precision test with one reflecting testing of actual value.
- This test does not test cash rounding rules. That should go into a different test.
- Correct expected value in test.
- Update app/Database/Seeds/TestDatabaseBootstrapSeeder.php
- Added check to testImportDeleteAttributeFromExistingItem
- Correct mocking of dropdowns
- Remove code depending on removed database.sql
- Removed FQN in seeder() call
- Added checks in Database seeder
- Moved the function to the attribute model where it belongs which allows testability.

Case Change Capability (CSV Import and Form)
- CSV Import and view Case Changes of `attribute_value`
- Store attribute even when just case is different.
- Add getAttributeValueByAttributeId() to assist in comparing the value
- Corrected Capitalization in File Handling Logic

CSV Import Attribute Link Deletion Capability
- Validation checks bypass magic word cells.
- Delete the attribute link for an item if the CSV contains `_DELETE_`
- Added calls to deleteOrphanedValues()
- Items CSV Import Attribute Delete
- Exclude the itemId in the check to see if the barcode number exists

Error Checking and Reporting Improvements
- Fail the import if an invalid stock location is found in the CSV
- Return false if deleteAttributeLinks fails
- Match sanitization of description field to Form submission import
- Fold errors into result and return value
- Populated $allowedStockLocations before sending it to the validation function
- Added logic to not ignore failed saveItemAttributes calls
- Add error checking to failed row insert
- Reworked &= to && logic so that it short-circuits the function call after if success is already false.
- Add transaction to storeCSVAttributeValue function to prevent deleting the attribute links before confirming the new value successfully saved.
- Modified generate_message in Db_log.php to be defensive.

Attribute Improvements
- Move ATTRIBUTE_VALUE_TYPES to the helper
- Normalize AttributeId in saveAttributeLink()
- normalize itemId in saveAttributeLink()
- Account for '0' in column values for allow_alt_description
- Remove duplicate saveAttributeValue call
- Correct return value of function
- Like other save_value() functions, the location_data variable is passed by reference.
- Unlike other save_value() functions, the location_data variable is not being updated with the primary key id.
- Added updateAttributeValue() function as part of logic fix.
- Added attribute_helper.php
- Simplified logic to store attribute values

---------

Signed-off-by: objec <objecttothis@gmail.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-04-09 11:13:22 +04:00

80 lines
1.9 KiB
PHP

<?php
namespace App\Events;
use Config\Database;
use Config\App;
class Db_log
{
private App $config;
/**
* @return void
*/
public function db_log_queries(): void
{
$this->config = config('App');
if ($this->config->db_log_enabled) {
$filepath = WRITEPATH . 'logs/Query-log-' . date('Y-m-d') . '.log';
$handle = fopen($filepath, "a+");
$message = $this->generate_message();
if (strlen($message) > 0) {
fwrite($handle, $message . "\n\n");
}
// Close the file
fclose($handle);
}
}
/**
* @return string
*/
private function generate_message(): string
{
$db = Database::connect();
$lastQuery = $db->getLastQuery();
if ($lastQuery === null) {
return '';
}
$affectedRows = $db->affectedRows();
$executionTime = $this->convert_time($lastQuery->getDuration());
$message = '*** Query: ' . date('Y-m-d H:i:s T') . ' *******************'
. "\n" . $lastQuery->getQuery()
. "\n Affected rows: $affectedRows"
. "\n Execution Time: " . $executionTime['time'] . ' ' . $executionTime['unit'];
$longQuery = ($executionTime['unit'] === 's') && ($executionTime['time'] > 0.5);
if ($longQuery) {
$message .= ' [LONG RUNNING QUERY]';
}
return $this->config->db_log_only_long && !$longQuery ? '' : $message;
}
/**
* @param float $time
* @return array
*/
private function convert_time(float $time): array
{
$unit = 's';
if ($time <= 0.1 && $time > 0.0001) {
$time = $time * 1000;
$unit = 'ms';
} elseif ($time <= 0.0001) {
$time = $time * 1000000;
$unit = 'µs';
}
return ['time' => $time, 'unit' => $unit];
}
}