Add handling for forced prices, arrays, and improved type checks

Introduced support for forced pricing in `addItemToOrder` and added stricter validation for array inputs in SQL queries. Enhanced JSON handling in type validation and improved code reuse with new objects. Added new endpoint `/modules/xlvask/related-orders` to fetch related orders by wash IDs.
This commit is contained in:
Jepp9350
2025-05-22 22:51:05 +02:00
parent b42c864bff
commit b837f572af
6 changed files with 87 additions and 7 deletions
+6 -1
View File
@@ -137,7 +137,7 @@ class order_items_o extends db
}
}
public function addItemToOrder(int $order_id, int $product_id, int $cashier_id, int $quantity, $related_item_id = null, $notes = null): void
public function addItemToOrder(int $order_id, int $product_id, int $cashier_id, int $quantity, $related_item_id = null, $notes = null, $forcePrice = null): void
{
global $db, $response;
try {
@@ -153,6 +153,11 @@ class order_items_o extends db
$price = $price - ($price * $discount / 100);
}
// If the price is forced, set the price to the forced price
if ($forcePrice) {
$price = (int)$forcePrice;
}
// Create a new record in the database
$sql = "INSERT INTO $this->table (order_id, product_id, price, cashier_id, quantity) VALUES ($order_id, $product_id, $price, $cashier_id, $quantity)";
$db->query($sql);
@@ -6,6 +6,7 @@ use classes\authentication;
use classes\response;
use classes\router;
use classes\xlvask;
use objects\orders_o;
use traits\route_t;
class moduleXLVaskRoute
@@ -116,5 +117,39 @@ class moduleXLVaskRoute
'modules_xlvask_internal_vehicle_types' => 'Get the vehicle types of the xlvask module'
]
);
$this->get('/modules/xlvask/related-orders', function () {
global $response;
self::requirePermission('modules_xlvask_related_orders');
self::requireParameters(['washIds']);
$washIds = self::getParameter('washIds');
// Check if the washIds is an array
self::requireType($washIds, self::TYPE_ARRAY());
// Require only strings in the array
foreach ( $washIds as $key => $value ) {
if (!is_string($value)) {
self::requireType($value, self::TYPE_STRING());
}
}
// Get all the related orders
$orders_o = new orders_o();
$mathing_orders = $orders_o->getFieldsWhere([
'wash_id' => $washIds,
'deleted_at' => null,
], [
'id',
'wash_id',
]);
$formatted_matches = [];
foreach ( $mathing_orders as $order ) {
$formatted_matches[(string)$order['wash_id']][] = (int)$order['id'];
}
$response->success($formatted_matches, 200);
},
[
'modules_xlvask_related_orders' => 'Get the related orders of the xlvask module'
]
);
}
}
+13 -1
View File
@@ -57,11 +57,23 @@ class orderItemsRoute
$notes = (string)self::getParameter('notes');
}
}
$price = null;
// Check if the price is set
if (self::isParametersSet(['price'])) {
// Check if the price is null, if so continue
if (self::getParameter('price') !== null) {
// Check if the price is a number
if (!is_numeric(self::getParameter('price'))) {
$response->error('Price must be a number', 400);
}
$price = (int)self::getParameter('price');
}
}
// Add the order item to the order This is done individually, to make the notes to the individual order items possible
$order_items = (new order_items_o());
// Add the order item to the order
$order_items->addItemToOrder((int)$data['order_id'], (int)$data['product_id'], (int)$user->id, (int)$data['quantity'], $related_item_id, $notes);
$order_items->addItemToOrder((int)$data['order_id'], (int)$data['product_id'], (int)$user->id, (int)$data['quantity'], $related_item_id, $notes, $price);
// Return the list of departments
$response->success(
$order_items->getItemAsArray()
+13 -4
View File
@@ -60,10 +60,13 @@ class ordersRoute
$response->success(
$orders->listObjectsWithPaginationIfSet(
function ($order) {
$order_obj = new orders_o();
// Get the order object
$order_obj->select((int)$order['id']);
// Add the invoice status to the order
$order['economic_invoice_module'] = (new economic_module_orders())->getByOrderId($order['id'])->asArray();
// Add the total amount to the order
$order['total_net_amount'] = (new orders_o())->select($order['id'])->getNetAmount();
$order['total_net_amount'] = $order_obj->getNetAmount();
// Add the stripe status to the order
$stripe_module_orders = (new stripe_module_orders_o())->select($order['id']);
if ($stripe_module_orders->exists()) {
@@ -71,11 +74,13 @@ class ordersRoute
}
// If the invoice collection is set, add it to the order
if (!empty($order['invoice_collection_id'])) {
$collected_order_invoices_obj = new collected_order_invoices_o();
$collected_order_invoices_obj->select((int)$order['invoice_collection_id']);
$order['invoice_collection'] = [
'id' => $order['invoice_collection_id'],
'closed_at' => (new collected_order_invoices_o())->select($order['invoice_collection_id'])->closed_at->value(),
'booked_invoice_id' => (new collected_order_invoices_o())->select($order['invoice_collection_id'])->booked_invoice_id->value() ?? null,
'processor' => (int)(new collected_order_invoices_o())->select($order['invoice_collection_id'])->processor->value() ?? null,
'closed_at' => $collected_order_invoices_obj->closed_at->value(),
'booked_invoice_id' => $collected_order_invoices_obj->booked_invoice_id->value() ?? null,
'processor' => (int)$collected_order_invoices_obj->processor->value() ?? null,
];
}
// Get the customer
@@ -207,6 +212,10 @@ class ordersRoute
if (isset($data['wash_id'])) {
$order->wash_id->set($data['wash_id']);
}
// Check if the created_at is set
if (isset($data['created_at'])) {
$order->created_at->set($data['created_at']);
}
// If the department ID is set, validate it
// Log the incident
(new logs_o())->add('orders', $order->department_id->value(), 1, $user->id, 'EDIT_ORDER', 'Successfully updated an order (ID: ' . $data['id'] . ')');
+14
View File
@@ -86,7 +86,21 @@ trait db_object_t
// If the value is null, add a where clause to check if the field is null
if ($value === null) {
$where[] = "$field IS NULL";
} elseif (is_array($value)) {
// If the value is an array, add a where clause to check if the field is in the array
$in = implode(',', array_map(function ($v) {
// Escape the value to prevent SQL injection
global $db;
return "'" . $db->escape_string($v) . "'";
}, $value));
$where[] = "$field IN ($in)";
} elseif (is_numeric($value)) {
// If the value is numeric, add a where clause to check if the field is equal to the value
$where[] = "$field = $value";
} else {
// Escape the value to prevent SQL injection
global $db;
$value = $db->escape_string($value);
$where[] = "$field = '$value'";
}
}
+6 -1
View File
@@ -34,6 +34,11 @@ trait route_t
$value_type = gettype($value);
// If the type is Array, or Object, json_decode the value to check if it is a valid JSON
if ($type === 'array' || $type === 'object') {
if (is_array($value)) {
$value = json_encode($value);
} elseif (is_object($value)) {
$value = json_encode($value);
}
$value = json_decode($value, true);
if (json_last_error() !== JSON_ERROR_NONE) {
global $response;
@@ -44,7 +49,7 @@ trait route_t
// Check if the value is of the required type
if ($value_type !== $type) {
global $response;
$response->error('Invalid type. Expected: ' . $type . ' Got: ' . $value_type . ' Value: ' . $value, 400);
$response->error('Invalid type. Expected: ' . $type . ' Got: ' . $value_type . ' Value: ' . (is_array($value) ? json_encode($value) : $value), 400);
}
return true;
}