mirror of
https://github.com/opensourcepos/opensourcepos.git
synced 2026-04-17 13:31:07 -04:00
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>
285 lines
9.0 KiB
PHP
285 lines
9.0 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use CodeIgniter\Database\ResultInterface;
|
|
use CodeIgniter\Model;
|
|
use CodeIgniter\Session\Session;
|
|
|
|
/**
|
|
* Stock_location class
|
|
*
|
|
* @property employee employee
|
|
* @property item item
|
|
* @property session session
|
|
*
|
|
*/
|
|
class Stock_location extends Model
|
|
{
|
|
protected $table = 'stock_locations';
|
|
protected $primaryKey = 'location_id';
|
|
protected $useAutoIncrement = true;
|
|
protected $useSoftDeletes = false;
|
|
protected $allowedFields = [
|
|
'location_name',
|
|
'deleted'
|
|
];
|
|
|
|
private Session $session;
|
|
private Employee $employee;
|
|
|
|
public function __construct()
|
|
{
|
|
parent::__construct();
|
|
|
|
$this->session = session();
|
|
}
|
|
|
|
/**
|
|
* @param int $location_id
|
|
* @return bool
|
|
*/
|
|
public function exists(int $location_id = NEW_ENTRY): bool
|
|
{
|
|
$builder = $this->db->table('stock_locations');
|
|
$builder->where('location_id', $location_id);
|
|
|
|
return ($builder->get()->getNumRows() >= 1);
|
|
}
|
|
|
|
/**
|
|
* @return ResultInterface
|
|
*/
|
|
public function get_all(): ResultInterface
|
|
{
|
|
$builder = $this->db->table('stock_locations');
|
|
$builder->where('deleted', 0);
|
|
|
|
return $builder->get();
|
|
}
|
|
|
|
/**
|
|
* @param string $module_id
|
|
* @return ResultInterface
|
|
*/
|
|
public function get_undeleted_all(string $module_id = 'items'): ResultInterface
|
|
{
|
|
$builder = $this->db->table('stock_locations');
|
|
$builder->join('permissions AS permissions', 'permissions.location_id = stock_locations.location_id');
|
|
$builder->join('grants AS grants', 'grants.permission_id = permissions.permission_id');
|
|
$builder->where('person_id', $this->session->get('person_id'));
|
|
$builder->like('permissions.permission_id', $module_id, 'after');
|
|
$builder->where('deleted', 0);
|
|
|
|
return $builder->get();
|
|
}
|
|
|
|
/**
|
|
* @param string $module_id
|
|
* @return bool
|
|
*/
|
|
public function show_locations(string $module_id = 'items'): bool
|
|
{
|
|
$stock_locations = $this->get_allowed_locations($module_id);
|
|
|
|
return count($stock_locations) > 1;
|
|
}
|
|
|
|
/**
|
|
* @return bool
|
|
*/
|
|
public function multiple_locations(): bool
|
|
{
|
|
return $this->get_all()->getNumRows() > 1;
|
|
}
|
|
|
|
/**
|
|
* @param string $module_id
|
|
* @return array
|
|
*/
|
|
public function get_allowed_locations(string $module_id = 'items'): array
|
|
{
|
|
$stock = $this->get_undeleted_all($module_id)->getResultArray();
|
|
$stock_locations = [];
|
|
|
|
foreach ($stock as $location_data) {
|
|
$stock_locations[$location_data['location_id']] = $location_data['location_name'];
|
|
}
|
|
|
|
return $stock_locations;
|
|
}
|
|
|
|
/**
|
|
* @param int $location_id
|
|
* @param string $module_id
|
|
* @return bool
|
|
*/
|
|
public function is_allowed_location(int $location_id, string $module_id = 'items'): bool
|
|
{
|
|
$builder = $this->db->table('stock_locations');
|
|
$builder->join('permissions AS permissions', 'permissions.location_id = stock_locations.location_id');
|
|
$builder->join('grants AS grants', 'grants.permission_id = permissions.permission_id');
|
|
$builder->where('person_id', $this->session->get('person_id'));
|
|
$builder->like('permissions.permission_id', $module_id, 'after');
|
|
$builder->where('stock_locations.location_id', $location_id);
|
|
$builder->where('deleted', 0);
|
|
|
|
return ($builder->get()->getNumRows() == 1); // TODO: ===
|
|
}
|
|
|
|
/**
|
|
* @param string $module_id
|
|
* @return int
|
|
*/
|
|
public function get_default_location_id(string $module_id = 'items'): int
|
|
{
|
|
$builder = $this->db->table('stock_locations');
|
|
$builder->join('permissions AS permissions', 'permissions.location_id = stock_locations.location_id');
|
|
$builder->join('grants AS grants', 'grants.permission_id = permissions.permission_id');
|
|
$builder->where('person_id', $this->session->get('person_id'));
|
|
$builder->like('permissions.permission_id', $module_id, 'after');
|
|
$builder->where('deleted', 0);
|
|
$builder->limit(1);
|
|
|
|
return $builder->get()->getRow()->location_id; // TODO: this is puking. Trying to get property 'location_id' of non-object
|
|
}
|
|
|
|
/**
|
|
* @param int $location_id
|
|
* @return string
|
|
*/
|
|
public function get_location_name(int $location_id): string
|
|
{
|
|
$builder = $this->db->table('stock_locations');
|
|
$builder->where('location_id', $location_id);
|
|
|
|
return $builder->get()->getRow()->location_name;
|
|
}
|
|
|
|
/**
|
|
* @param string $location_name
|
|
* @return int
|
|
*/
|
|
public function get_location_id(string $location_name): int
|
|
{
|
|
$builder = $this->db->table('stock_locations');
|
|
$builder->where('location_name', $location_name);
|
|
|
|
return $builder->get()->getRow()->location_id;
|
|
}
|
|
|
|
/**
|
|
* @param array $location_data
|
|
* @param int $location_id
|
|
* @return bool
|
|
*/
|
|
public function save_value(array &$location_data, int $location_id): bool
|
|
{
|
|
$location_name = $location_data['location_name'];
|
|
|
|
$location_data_to_save = ['location_name' => $location_name, 'deleted' => 0];
|
|
|
|
if (!$this->exists($location_id)) {
|
|
$this->db->transStart();
|
|
|
|
$builder = $this->db->table('stock_locations');
|
|
$builder->insert($location_data_to_save);
|
|
$location_id = $this->db->insertID();
|
|
$location_data['location_id'] = $location_id;
|
|
|
|
$this->_insert_new_permission('items', $location_id, $location_name); // TODO: need to refactor out the hungarian notation.
|
|
$this->_insert_new_permission('sales', $location_id, $location_name);
|
|
$this->_insert_new_permission('receivings', $location_id, $location_name);
|
|
|
|
// Insert quantities for existing items
|
|
$item = model(Item::class);
|
|
$builder = $this->db->table('item_quantities');
|
|
$items = $item->get_all();
|
|
|
|
foreach ($items->getResultArray() as $item) {
|
|
$quantity_data = [
|
|
'item_id' => $item['item_id'],
|
|
'location_id' => $location_id,
|
|
'quantity' => 0
|
|
];
|
|
$builder->insert($quantity_data);
|
|
}
|
|
|
|
$this->db->transComplete();
|
|
|
|
return $this->db->transStatus();
|
|
}
|
|
|
|
$original_location_name = $this->get_location_name($location_id);
|
|
|
|
if ($original_location_name != $location_name) {
|
|
$builder = $this->db->table('permissions');
|
|
$builder->delete(['location_id' => $location_id]);
|
|
|
|
$this->_insert_new_permission('items', $location_id, $location_name);
|
|
$this->_insert_new_permission('sales', $location_id, $location_name);
|
|
$this->_insert_new_permission('receivings', $location_id, $location_name);
|
|
}
|
|
|
|
$builder = $this->db->table('stock_locations');
|
|
$builder->where('location_id', $location_id);
|
|
|
|
return $builder->update($location_data_to_save);
|
|
}
|
|
|
|
/**
|
|
* @param string $module
|
|
* @param int $location_id
|
|
* @param string $location_name
|
|
* @return void
|
|
*/
|
|
private function _insert_new_permission(string $module, int $location_id, string $location_name): void // TODO: refactor out hungarian notation
|
|
{
|
|
// Insert new permission for stock location
|
|
$permission_id = $module . '_' . str_replace(' ', '_', $location_name); // TODO: String interpolation
|
|
$permission_data = ['permission_id' => $permission_id, 'module_id' => $module, 'location_id' => $location_id];
|
|
|
|
$builder = $this->db->table('permissions');
|
|
$builder->insert($permission_data);
|
|
|
|
// Insert grants for new permission
|
|
$employee = model(Employee::class);
|
|
$employees = $employee->get_all();
|
|
|
|
$builder = $this->db->table('grants');
|
|
|
|
foreach ($employees->getResultArray() as $employee) {
|
|
$this->employee = model(Employee::class);
|
|
|
|
// Retrieve the menu_group assigned to the grant for the module and use that for the new stock locations
|
|
$menu_group = $this->employee->get_menu_group($module, $employee['person_id']);
|
|
|
|
$grants_data = ['permission_id' => $permission_id, 'person_id' => $employee['person_id'], 'menu_group' => $menu_group];
|
|
|
|
$builder->insert($grants_data);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Deletes one item
|
|
* @param int|null $location_id
|
|
* @param bool $purge
|
|
* @return bool
|
|
*/
|
|
public function delete($location_id = null, bool $purge = false): bool
|
|
{
|
|
$this->db->transStart();
|
|
|
|
$builder = $this->db->table('stock_locations');
|
|
$builder->where('location_id', $location_id);
|
|
$builder->update(['deleted' => 1]);
|
|
|
|
$builder = $this->db->table('permissions');
|
|
$builder->delete(['location_id' => $location_id]);
|
|
|
|
$this->db->transComplete();
|
|
|
|
return $this->db->transStatus();
|
|
}
|
|
}
|