Compare commits

..

1 Commits

Author SHA1 Message Date
jekkos
2d8fb735c3 Add a check to see if account_number is valid key (#4257) 2025-05-31 00:30:09 +02:00
10 changed files with 83 additions and 87 deletions

View File

@@ -1,5 +1,4 @@
[unreleased]: https://github.com/opensourcepos/opensourcepos/compare/3.4.0...HEAD
[3.4.1]: https://github.com/opensourcepos/opensourcepos/compare/3.4.0...3.4.1
[3.4.0]: https://github.com/opensourcepos/opensourcepos/compare/3.3.9...3.4.0
[3.3.9]: https://github.com/opensourcepos/opensourcepos/compare/3.3.8...3.3.9
[3.3.8]: https://github.com/opensourcepos/opensourcepos/compare/3.3.7...3.3.8

View File

@@ -12,7 +12,7 @@ class App extends BaseConfig
*
* @var string
*/
public string $application_version = '3.4.1';
public string $application_version = '3.4.0';
/**
* This is the commit hash for the version you are currently using.

View File

@@ -168,7 +168,7 @@ class Receivings extends Secure_Controller
$data = [];
$mode = $this->receiving_lib->get_mode();
$item_id_or_number_or_item_kit_or_receipt = $this->request->getPost('item', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$item_id_or_number_or_item_kit_or_receipt = (int)$this->request->getPost('item', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$this->token_lib->parse_barcode($quantity, $price, $item_id_or_number_or_item_kit_or_receipt);
$quantity = ($mode == 'receive' || $mode == 'requisition') ? $quantity : -$quantity;
$item_location = $this->receiving_lib->get_stock_source();

View File

@@ -658,11 +658,11 @@ class Sales extends Secure_Controller
$data['company_info'] = implode("\n", [$this->config['address'], $this->config['phone']]);
if ($this->config['account_number']) {
if (isset($this->config['account_number'])) {
$data['company_info'] .= "\n" . lang('Sales.account_number') . ": " . $this->config['account_number'];
}
if ($this->config['tax_id'] != '') {
if (isset($this->config['tax_id'])) {
$data['company_info'] .= "\n" . lang('Sales.tax_id') . ": " . $this->config['tax_id'];
}

View File

@@ -76,13 +76,7 @@ function createPrimaryKey(string $table, string $index): void {
$constraints = dropAllForeignKeyConstraints($table, $index);
deleteIndex($table, $index);
$forge = Database::forge();
if (isMariaDb()) {
$forge->addPrimaryKey($index);
} else {
$forge->addPrimaryKey($index, 'PRIMARY');
}
$forge->addPrimaryKey($index,'PRIMARY');
$forge->processIndexes($table);
recreateForeignKeyConstraints($constraints);
}
@@ -211,16 +205,3 @@ function foreignKeyExists(string $constraintName, string $tableName): bool {
return $query->getNumRows() > 0;
}
/**
* Checks if the current database is MariaDB.
*
* @return bool true if the database is MariaDB, false otherwise.
*/
function isMariaDb(): bool
{
$db = Database::connect();
$version = $db->getVersion();
return stripos($version, 'mariadb') !== false;
}

View File

@@ -256,99 +256,117 @@ class Receiving_lib
// TODO: This array signature needs to be reworked. It's way too long. Perhaps an object needs to be passed rather than these?
/**
* @param string $itemId
* @param int $item_id
* @param int $quantity
* @param int|null $itemLocation
* @param int|null $item_location
* @param float $discount
* @param int $discountType
* @param int $discount_type
* @param float|null $price
* @param string|null $description
* @param string|null $serialNumber
* @param float|null $receivingQuantity
* @param int|null $receivingId
* @param bool $includeDeleted
* @param string|null $serialnumber
* @param float|null $receiving_quantity
* @param int|null $receiving_id
* @param bool $include_deleted
* @return bool
*/
public function add_item(string $itemId, int $quantity = 1, ?int $itemLocation = null, float $discount = 0, int $discountType = 0, ?float $price = null, ?string $description = null, ?string $serialNumber = null, ?float $receivingQuantity = null, ?int $receivingId = null, bool $includeDeleted = false): bool
public function add_item(int $item_id, int $quantity = 1, ?int $item_location = null, float $discount = 0, int $discount_type = 0, ?float $price = null, ?string $description = null, ?string $serialnumber = null, ?float $receiving_quantity = null, ?int $receiving_id = null, bool $include_deleted = false): bool
{
$config = config(OSPOS::class)->settings;
$itemInfo = $this->item->get_info_by_id_or_number($itemId, $includeDeleted);
if (empty($itemInfo)) {
return false;
// Make sure item exists in database.
if (!$this->item->exists($item_id, $include_deleted)) {
// Try to get item id given an item_number
$item_id = $this->item->get_item_id($item_id, $include_deleted);
if (!$item_id) {
return false;
}
}
$itemId = $itemInfo->item_id;
// Get items in the receiving so far.
$items = $this->get_cart();
$maxKey = 0;
$itemAlreadyInSale = false;
$updateKey = 0;
// We need to loop through all items in the cart.
// If the item is already there, get it's key($updatekey).
// We also need to get the next key that we are going to use in case we need to add the
// item to the list. Since items can be deleted, we can't use a count. we use the highest key + 1.
$maxkey = 0; // Highest key so far
$itemalreadyinsale = false; // We did not find the item yet.
$updatekey = 0; // Key to use to update(quantity)
foreach ($items as $item) {
if ($maxKey <= $item['line']) {
$maxKey = $item['line'];
// We primed the loop so maxkey is 0 the first time.
// Also, we have stored the key in the element itself, so we can compare.
// There is an array public function to get the associated key for an element, but I like it better
// like that!
if ($maxkey <= $item['line']) {
$maxkey = $item['line'];
}
if ($item['item_id'] == $itemId && $item['item_location'] == $itemLocation) {
$itemAlreadyInSale = true;
$updateKey = $item['line'];
if ($item['item_id'] == $item_id && $item['item_location'] == $item_location) {
$itemalreadyinsale = true;
$updatekey = $item['line'];
}
}
$insertKey = $maxKey + 1;
$itemInfo = $this->item->get_info((int) $itemId);
$insertkey = $maxkey + 1;
$item_info = $this->item->get_info($item_id);
$price = $price != null ? $price : $itemInfo->cost_price;
// Array records are identified by $insertkey and item_id is just another field.
$price = $price != null ? $price : $item_info->cost_price;
if ($config['multi_pack_enabled']) {
$itemInfo->name .= NAME_SEPARATOR . $itemInfo->pack_name;
$item_info->name .= NAME_SEPARATOR . $item_info->pack_name;
}
if ($itemInfo->receiving_quantity == 0 || $itemInfo->receiving_quantity == 1) {
$receivingQuantityChoices = [1 => 'x1'];
if ($item_info->receiving_quantity == 0 || $item_info->receiving_quantity == 1) {
$receiving_quantity_choices = [1 => 'x1'];
} else {
$receivingQuantityChoices = [
to_quantity_decimals($itemInfo->receiving_quantity) => 'x' . to_quantity_decimals($itemInfo->receiving_quantity),
1 => 'x1'
$receiving_quantity_choices = [
to_quantity_decimals($item_info->receiving_quantity) => 'x' . to_quantity_decimals($item_info->receiving_quantity),
1 => 'x1'
];
}
if (is_null($receivingQuantity)) {
$receivingQuantity = $itemInfo->receiving_quantity;
if (is_null($receiving_quantity)) {
$receiving_quantity = $item_info->receiving_quantity;
}
$attributeLinks = $this->attribute->get_link_values((int) $itemId, 'receiving_id', $receivingId, Attribute::SHOW_IN_RECEIVINGS)->getRowObject();
$attribute_links = $this->attribute->get_link_values($item_id, 'receiving_id', $receiving_id, Attribute::SHOW_IN_RECEIVINGS)->getRowObject();
$item = [
$insertKey => [
'item_id' => $itemId,
'item_location' => $itemLocation,
'item_number' => $itemInfo->item_number,
'stock_name' => $this->stock_location->get_location_name($itemLocation),
'line' => $insertKey,
'name' => $itemInfo->name,
'description' => $description != null ? $description : $itemInfo->description,
'serialnumber' => $serialNumber != null ? $serialNumber : '',
'attribute_values' => $attributeLinks->attribute_values,
'attribute_dtvalues' => $attributeLinks->attribute_dtvalues,
'allow_alt_description' => $itemInfo->allow_alt_description,
'is_serialized' => $itemInfo->is_serialized,
$insertkey => [
'item_id' => $item_id,
'item_location' => $item_location,
'item_number' => $item_info->item_number,
'stock_name' => $this->stock_location->get_location_name($item_location),
'line' => $insertkey,
'name' => $item_info->name,
'description' => $description != null ? $description : $item_info->description,
'serialnumber' => $serialnumber != null ? $serialnumber : '',
'attribute_values' => $attribute_links->attribute_values,
'attribute_dtvalues' => $attribute_links->attribute_dtvalues,
'allow_alt_description' => $item_info->allow_alt_description,
'is_serialized' => $item_info->is_serialized,
'quantity' => $quantity,
'discount' => $discount,
'discount_type' => $discountType,
'in_stock' => $this->item_quantity->get_item_quantity((int) $itemId, $itemLocation)->quantity,
'discount_type' => $discount_type,
'in_stock' => $this->item_quantity->get_item_quantity($item_id, $item_location)->quantity,
'price' => $price,
'receiving_quantity' => $receivingQuantity,
'receiving_quantity_choices' => $receivingQuantityChoices,
'total' => $this->get_item_total($quantity, $price, $discount, $discountType, $receivingQuantity)
'receiving_quantity' => $receiving_quantity,
'receiving_quantity_choices' => $receiving_quantity_choices,
'total' => $this->get_item_total($quantity, $price, $discount, $discount_type, $receiving_quantity)
]
];
if ($itemAlreadyInSale) {
$items[$updateKey]['quantity'] += $quantity;
$items[$updateKey]['total'] = $this->get_item_total($items[$updateKey]['quantity'], $price, $discount, $discountType, $items[$updateKey]['receiving_quantity']);
// Item already exists
if ($itemalreadyinsale) { // TODO: This variable does not adhere to naming conventions.
$items[$updatekey]['quantity'] += $quantity;
$items[$updatekey]['total'] = $this->get_item_total($items[$updatekey]['quantity'], $price, $discount, $discount_type, $items[$updatekey]['receiving_quantity']);
} else {
// Add to existing array
$items += $item;
}

View File

@@ -944,7 +944,7 @@ class Sale_lib
// TODO: this function needs to be reworked... way too many parameters. Also, optional parameters must go after mandatory parameters.
/**
* @param string $item_id
* @param int $item_id
* @param int $item_location
* @param string $quantity
* @param string $discount
@@ -961,7 +961,7 @@ class Sale_lib
* @param bool|null $line
* @return bool
*/
public function add_item(string &$item_id, int $item_location, string $quantity = '1', string &$discount = '0.0', int $discount_type = 0, int $price_mode = PRICE_MODE_STANDARD, ?int $kit_price_option = null, ?int $kit_print_option = null, ?string $price_override = null, ?string $description = null, ?string $serialnumber = null, ?int $sale_id = null, bool $include_deleted = false, ?bool $print_option = null, ?bool $line = null): bool
public function add_item(int &$item_id, int $item_location, string $quantity = '1', string &$discount = '0.0', int $discount_type = 0, int $price_mode = PRICE_MODE_STANDARD, ?int $kit_price_option = null, ?int $kit_print_option = null, ?string $price_override = null, ?string $description = null, ?string $serialnumber = null, ?int $sale_id = null, bool $include_deleted = false, ?bool $print_option = null, ?bool $line = null): bool
{
$item_info = $this->item->get_info_by_id_or_number($item_id, $include_deleted);

View File

@@ -47,11 +47,10 @@ class Item extends Model
/**
* Determines if a given item_id is an item
*/
public function exists(string $item_id, bool $ignore_deleted = false, bool $deleted = false): bool
public function exists(int $item_id, bool $ignore_deleted = false, bool $deleted = false): bool
{
$builder = $this->db->table('items');
$builder->where('item_id', $item_id);
$builder->orWhere('item_number', $item_id);
if (!$ignore_deleted) {
$builder->where('deleted', $deleted);
@@ -337,7 +336,7 @@ class Item extends Model
/**
* Gets information about a particular item by item id or number
*/
public function get_info_by_id_or_number(string $item_id, bool $include_deleted = true)
public function get_info_by_id_or_number(int $item_id, bool $include_deleted = true)
{
$builder = $this->db->table('items');
$builder->groupStart();
@@ -371,12 +370,11 @@ class Item extends Model
/**
* Get an item id given an item number
*/
public function get_item_id(string $item_number, bool $ignore_deleted = false, bool $deleted = false): bool|int
public function get_item_id(string $item_number, bool $ignore_deleted = false, bool $deleted = false): bool
{
$builder = $this->db->table('items');
$builder->join('suppliers', 'suppliers.person_id = items.supplier_id', 'left');
$builder->where('item_number', $item_number);
$builder->orWhere('item_id', $item_number);
if (!$ignore_deleted) {
$builder->where('items.deleted', $deleted);

View File

@@ -15,7 +15,7 @@ networks:
services:
ospos:
image: jekkos/opensourcepos:3.4.1
image: jekkos/opensourcepos:3.4.0
restart: always
depends_on:
- mysql

View File

@@ -1,6 +1,6 @@
{
"name": "@opensourcepos/opensourcepos",
"version": "3.4.1",
"version": "3.4.0",
"description": "Open Source Point of Sale is a web based point of sale system written in the PHP language. It uses MySQL as the data storage back-end and has a simple user interface.",
"main": "index.php",
"license": "MIT",