Skip to content

Commit

Permalink
- Converted raw queries to QueryBuilder where possible
Browse files Browse the repository at this point in the history
- Removed completed TODOs
- Added TODOs and comments where needed.

Signed-off-by: objecttothis <[email protected]>
  • Loading branch information
objecttothis authored and jekkos committed Jun 15, 2024
1 parent 1328b4d commit 63ae549
Show file tree
Hide file tree
Showing 4 changed files with 253 additions and 226 deletions.
31 changes: 23 additions & 8 deletions app/Models/Attribute.php
Original file line number Diff line number Diff line change
Expand Up @@ -450,36 +450,51 @@ private function convert_definition_data(int $definition_id, string $from_type,
$checkbox_attribute_values = $this->checkbox_attribute_values($definition_id);

$this->db->transStart();
//TODO: We should see if we can convert these queries to use query builder from CI4.

$query = 'UPDATE '. $this->db->prefixTable('attribute_links') .' links ';
$query .= 'JOIN '. $this->db->prefixTable('attribute_values') .' vals ';
$query .= 'ON vals.attribute_id = links.attribute_id ';
$query .= "SET links.attribute_id = IF((attribute_value IN('false','0','') OR (attribute_value IS NULL)), $checkbox_attribute_values[0], $checkbox_attribute_values[1]) ";
$query .= 'WHERE definition_id = '. $this->db->escape($definition_id);
$success = $this->db->query($query);

//TODO: In order to convert this query to QueryBuilder, CI needs to fix their issue with JOINs being ignored in UPDATE queries and ideally fix their issue with backticks and dbprefix not being prepended when SQL functions are used.
//Replace the code above with the code below when it's fixed.
// $db_prefix = $this->db->getPrefix();
// $builder = $this->db->table('attribute_links');
// $builder->join('attribute_values', 'attribute_values.attribute_id = attribute_links.attribute_id', 'inner');
// $builder->set('attribute_links.attribute_id', "IF((`$db_prefix" . "attribute_values`.`attribute_value` IN('false','0','') OR (`". $db_prefix ."attribute_values`.`attribute_value` IS NULL)), $checkbox_attribute_values[0], $checkbox_attribute_values[1])", false);
// $builder->where('attribute_links.definition_id', $definition_id);
// $success = $builder->update();

$this->db->transComplete();
}
}
else if($from_type === DROPDOWN)
{
if(in_array($to_type, [TEXT, CHECKBOX], true)) //TODO: This if statement is possibly unnecessary... unless we have it there so that later we can do something with TEXT types also.
if(in_array($to_type, [TEXT, CHECKBOX], true))
{
if($to_type === CHECKBOX) //TODO: Duplicated code.
{
$checkbox_attribute_values = $this->checkbox_attribute_values($definition_id);

$this->db->transStart();
//TODO: We should see if we can convert these queries to use query builder from CI4. Likely we need to do this using RawSql() https://codeigniter.com/user_guide/database/query_builder.html?highlight=rawsql#query-builder-where-rawsql
//TODO: We should see if we can refactor a function out of this block and the identical block above it.

$query = 'UPDATE '. $this->db->prefixTable('attribute_links') .' links ';
$query .= 'JOIN '. $this->db->prefixTable('attribute_values') .' vals ';
$query .= 'ON vals.attribute_id = links.attribute_id ';
$query .= "SET links.attribute_id = IF((attribute_value IN('false','0','') OR (attribute_value IS NULL)), $checkbox_attribute_values[0], $checkbox_attribute_values[1]) ";
$query .= 'WHERE definition_id = '. $this->db->escape($definition_id);
$success = $this->db->query($query);

$this->db->transComplete();
//TODO: Same issue here. Replace the code above with the code below when it's fixed.
// $builder = $this->db->table('attribute_links');
// $builder->join('attribute_values', 'attribute_values.attribute_id = attribute_links.attribute_id', 'inner');
// $builder->set('attribute_links.attribute_id', "IF((attribute_value IN('false','0','') OR (attribute_value IS NULL)), $checkbox_attribute_values[0], $checkbox_attribute_values[1])", false);
// $builder->where('definition_id', $definition_id);
// $success = $builder->update();
//
// $this->db->transComplete();
}
}
}
Expand Down Expand Up @@ -906,11 +921,11 @@ public function save_value(string $attribute_value, int $definition_id, $item_id
/**
* @param string $attribute_value
* @param int $definition_id
* @return bool|BaseResult|Query
* @return bool
*/
public function delete_value(string $attribute_value, int $definition_id): Query|bool|BaseResult
public function delete_value(string $attribute_value, int $definition_id): bool
{
//TODO: convert to using QueryBuilder. Use App/Models/Reports/Summary_taxes.php getData() as a reference template
//QueryBuilder does not support multi-table delete.
$query = 'DELETE atrv, atrl ';
$query .= 'FROM ' . $this->db->prefixTable('attribute_values') . ' atrv, ' . $this->db->prefixTable('attribute_links') . ' atrl ';
$query .= 'WHERE atrl.attribute_id = atrv.attribute_id AND atrv.attribute_value = ' . $this->db->escape($attribute_value);
Expand Down
49 changes: 23 additions & 26 deletions app/Models/Customer.php
Original file line number Diff line number Diff line change
Expand Up @@ -141,35 +141,32 @@ private function getEmptyObject(string $table_name): object
*/
public function get_stats(int $customer_id)
{
// create a temporary table to contain all the sum and average of items
$sql = 'CREATE TEMPORARY TABLE IF NOT EXISTS ' . $this->db->prefixTable('sales_items_temp');
$sql .= ' (INDEX(sale_id)) ENGINE=MEMORY
(
SELECT
sales.sale_id AS sale_id,
AVG(sales_items.discount) AS avg_discount,
SUM(sales_items.quantity_purchased) AS quantity
FROM ' . $this->db->prefixTable('sales') . ' AS sales
INNER JOIN ' . $this->db->prefixTable('sales_items') . ' AS sales_items
ON sales_items.sale_id = sales.sale_id
WHERE sales.customer_id = ' . $this->db->escape($customer_id) . '
GROUP BY sale_id
)';
$this->db->query($sql);

$db_prefix = $this->db->getPrefix();
$totals_decimals = totals_decimals();
$quantity_decimals = quantity_decimals();

//Temp Table
$builder = $this->db->table('sales');
$builder->select('sales.sale_id AS sale_id, AVG(`' . $db_prefix . 'sales_items`.`discount`) AS avg_discount, SUM(`' . $db_prefix . 'sales_items`.`quantity_purchased`) AS quantity');
$builder->join('sales_items', 'sales_items.sale_id = sales.sale_id');
$builder->where('sales.customer_id', $customer_id);
$builder->groupBy('sale_id');
$selectQuery = $builder->getCompiledSelect();

$sql = 'CREATE TEMPORARY TABLE IF NOT EXISTS ' . $this->db->prefixTable('sales_items_temp');
$sql .= ' (INDEX(sale_id)) ENGINE=MEMORY (' . $selectQuery . ')';
$this->db->query($sql);

//Get data
$builder = $this->db->table('sales');
$builder->select('
SUM(sales_payments.payment_amount - sales_payments.cash_refund) AS total,
MIN(sales_payments.payment_amount - sales_payments.cash_refund) AS min,
MAX(sales_payments.payment_amount - sales_payments.cash_refund) AS max,
AVG(sales_payments.payment_amount - sales_payments.cash_refund) AS average,
' . "
ROUND(AVG(sales_items_temp.avg_discount), $totals_decimals) AS avg_discount,
ROUND(SUM(sales_items_temp.quantity), $quantity_decimals) AS quantity
");
$builder->select([
'SUM(sales_payments.payment_amount - sales_payments.cash_refund) AS total',
'MIN(sales_payments.payment_amount - sales_payments.cash_refund) AS min',
'MAX(sales_payments.payment_amount - sales_payments.cash_refund) AS max',
'AVG(sales_payments.payment_amount - sales_payments.cash_refund) AS average',
"ROUND(AVG(sales_items_temp.avg_discount), $totals_decimals) AS avg_discount",
"ROUND(SUM(sales_items_temp.quantity), $quantity_decimals) AS quantity"
]);
$builder->join('sales_payments AS sales_payments', 'sales.sale_id = sales_payments.sale_id');
$builder->join('sales_items_temp AS sales_items_temp', 'sales.sale_id = sales_items_temp.sale_id');
$builder->where('sales.customer_id', $customer_id);
Expand All @@ -178,7 +175,7 @@ public function get_stats(int $customer_id)

$stat = $builder->get()->getRow();

// drop the temporary table to contain memory consumption as it's no longer required
//Drop Temp Table
$sql = 'DROP TEMPORARY TABLE IF EXISTS ' . $this->db->prefixTable('sales_items_temp');
$this->db->query($sql);

Expand Down
84 changes: 39 additions & 45 deletions app/Models/Receiving.php
Original file line number Diff line number Diff line change
Expand Up @@ -313,60 +313,54 @@ public function get_payment_options(): array
public function create_temp_table(array $inputs): void
{
$config = config(OSPOS::class)->settings;
$db_prefix = $this->db->getPrefix();

if(empty($inputs['receiving_id']))
{
if(empty($config['date_or_time_format']))
{
$where = 'WHERE DATE(receiving_time) BETWEEN ' . $this->db->escape($inputs['start_date']) . ' AND ' . $this->db->escape($inputs['end_date']);
}
else
{
$where = 'WHERE receiving_time BETWEEN ' . $this->db->escape(rawurldecode($inputs['start_date'])) . ' AND ' . $this->db->escape(rawurldecode($inputs['end_date']));
}
$where = empty($config['date_or_time_format'])
? 'DATE(`receiving_time`) BETWEEN ' . $this->db->escape($inputs['start_date']) . ' AND ' . $this->db->escape($inputs['end_date'])
: 'receiving_time BETWEEN ' . $this->db->escape(rawurldecode($inputs['start_date'])) . ' AND ' . $this->db->escape(rawurldecode($inputs['end_date']));
}
else
{
$where = 'WHERE receivings_items.receiving_id = ' . $this->db->escape($inputs['receiving_id']);
$where = 'receivings_items.receiving_id = ' . $this->db->escape($inputs['receiving_id']);
}

$builder = $this->db->table('receivings_items');
$builder->select([
'MAX(DATE(`receiving_time`)) AS receiving_date',
'MAX(`receiving_time`) AS receiving_time',
'receivings_items.receiving_id AS receiving_id',
'MAX(`comment`) AS comment',
'MAX(`item_location`) AS item_location',
'MAX(`reference`) AS reference',
'MAX(`payment_type`) AS payment_type',
'MAX(`employee_id`) AS employee_id',
'items.item_id AS item_id',
'MAX(`'. $db_prefix .'receivings`.`supplier_id`) AS supplier_id',
'MAX(`quantity_purchased`) AS quantity_purchased',
'MAX(`'. $db_prefix .'receivings_items`.`receiving_quantity`) AS item_receiving_quantity',
'MAX(`item_cost_price`) AS item_cost_price',
'MAX(`item_unit_price`) AS item_unit_price',
'MAX(`discount`) AS discount',
'MAX(`discount_type`) AS discount_type',
'receivings_items.line AS line',
'MAX(`serialnumber`) AS serialnumber',
'MAX(`'. $db_prefix .'receivings_items`.`description`) AS description',
'MAX(CASE WHEN `'. $db_prefix .'receivings_items`.`discount_type` = ' . PERCENT . ' THEN `item_unit_price` * `quantity_purchased` * `'. $db_prefix .'receivings_items`.`receiving_quantity` - `item_unit_price` * `quantity_purchased` * `'. $db_prefix .'receivings_items`.`receiving_quantity` * `discount` / 100 ELSE `item_unit_price` * `quantity_purchased` * `'. $db_prefix .'receivings_items`.`receiving_quantity` - `discount` END) AS subtotal',
'MAX(CASE WHEN `'. $db_prefix .'receivings_items`.`discount_type` = ' . PERCENT . ' THEN `item_unit_price` * `quantity_purchased` * `'. $db_prefix .'receivings_items`.`receiving_quantity` - `item_unit_price` * `quantity_purchased` * `'. $db_prefix .'receivings_items`.`receiving_quantity` * `discount` / 100 ELSE `item_unit_price` * `quantity_purchased` * `'. $db_prefix .'receivings_items`.`receiving_quantity` - `discount` END) AS total',
'MAX((CASE WHEN `'. $db_prefix .'receivings_items`.`discount_type` = ' . PERCENT . ' THEN `item_unit_price` * `quantity_purchased` * `'. $db_prefix .'receivings_items`.`receiving_quantity` - `item_unit_price` * `quantity_purchased` * `'. $db_prefix .'receivings_items`.`receiving_quantity` * `discount` / 100 ELSE `item_unit_price` * `quantity_purchased` * `'. $db_prefix .'receivings_items`.`receiving_quantity` - discount END) - (`item_cost_price` * `quantity_purchased`)) AS profit',
'MAX(`item_cost_price` * `quantity_purchased` * `'. $db_prefix .'receivings_items`.`receiving_quantity` ) AS cost'
]);
$builder->join('receivings', 'receivings_items.receiving_id = receivings.receiving_id', 'inner');
$builder->join('items', 'receivings_items.item_id = items.item_id', 'inner');
$builder->where($where);
$builder->groupBy(['receivings_items.receiving_id', 'items.item_id', 'receivings_items.line']);
$selectQuery = $builder->getCompiledSelect();

//QueryBuilder does not support creating temporary tables.
$sql = 'CREATE TEMPORARY TABLE IF NOT EXISTS ' . $this->db->prefixTable('receivings_items_temp') .
' (INDEX(receiving_date), INDEX(receiving_time), INDEX(receiving_id))
(
SELECT
MAX(DATE(receiving_time)) AS receiving_date,
MAX(receiving_time) AS receiving_time,
receivings_items.receiving_id AS receiving_id,
MAX(comment) AS comment,
MAX(item_location) AS item_location,
MAX(reference) AS reference,
MAX(payment_type) AS payment_type,
MAX(employee_id) AS employee_id,
items.item_id AS item_id,
MAX(receivings.supplier_id) AS supplier_id,
MAX(quantity_purchased) AS quantity_purchased,
MAX(receivings_items.receiving_quantity) AS item_receiving_quantity,
MAX(item_cost_price) AS item_cost_price,
MAX(item_unit_price) AS item_unit_price,
MAX(discount) AS discount,
MAX(discount_type) AS discount_type,
receivings_items.line AS line,
MAX(serialnumber) AS serialnumber,
MAX(receivings_items.description) AS description,
MAX(CASE WHEN receivings_items.discount_type = ' . PERCENT . ' THEN item_unit_price * quantity_purchased * receivings_items.receiving_quantity - item_unit_price * quantity_purchased * receivings_items.receiving_quantity * discount / 100 ELSE item_unit_price * quantity_purchased * receivings_items.receiving_quantity - discount END) AS subtotal,
MAX(CASE WHEN receivings_items.discount_type = ' . PERCENT . ' THEN item_unit_price * quantity_purchased * receivings_items.receiving_quantity - item_unit_price * quantity_purchased * receivings_items.receiving_quantity * discount / 100 ELSE item_unit_price * quantity_purchased * receivings_items.receiving_quantity - discount END) AS total,
MAX((CASE WHEN receivings_items.discount_type = ' . PERCENT . ' THEN item_unit_price * quantity_purchased * receivings_items.receiving_quantity - item_unit_price * quantity_purchased * receivings_items.receiving_quantity * discount / 100 ELSE item_unit_price * quantity_purchased * receivings_items.receiving_quantity - discount END) - (item_cost_price * quantity_purchased)) AS profit,
MAX(item_cost_price * quantity_purchased * receivings_items.receiving_quantity ) AS cost
FROM ' . $this->db->prefixTable('receivings_items') . ' AS receivings_items
INNER JOIN ' . $this->db->prefixTable('receivings') . ' AS receivings
ON receivings_items.receiving_id = receivings.receiving_id
INNER JOIN ' . $this->db->prefixTable('items') . ' AS items
ON receivings_items.item_id = items.item_id
' . "
$where
" . '
GROUP BY receivings_items.receiving_id, items.item_id, receivings_items.line
)';
' (INDEX(receiving_date), INDEX(receiving_time), INDEX(receiving_id)) AS (' . $selectQuery . ')';

$this->db->query($sql);
}
Expand Down
Loading

0 comments on commit 63ae549

Please sign in to comment.