Add getOrdersWithPossibleDuplicates method in orders_o and getPossibleDuplicates method in InvoicingPeriodRoute to identify and handle potential duplicate orders within a specified date range.

This commit is contained in:
Jepp9350
2025-06-30 17:39:11 +02:00
parent 6b80637208
commit e583a269d0
2 changed files with 107 additions and 16 deletions
+70
View File
@@ -870,4 +870,74 @@ class orders_o extends db
}
return $transactions;
}
/**
* @throws Exception
*/
public function getOrdersWithPossibleDuplicates(string $dateFrom, string $dateTo): array
{
global $db;
// Validate the date range
if (strtotime($dateFrom) === false || strtotime($dateTo) === false) {
throw new Exception('Invalid date range provided');
}
if (strtotime($dateFrom) > strtotime($dateTo)) {
throw new Exception('The start date cannot be after the end date');
}
// Prepare the SQL query to find orders with possible duplicates in the date range
$dateFrom = $db->escape_string($dateFrom);
$dateTo = $db->escape_string($dateTo);
$sql = "SELECT id, customer_id, reg_1, created_at FROM $this->table WHERE created_at BETWEEN '$dateFrom' AND '$dateTo' AND deleted_at IS NULL";
$result = $db->query($sql);
if ($result->num_rows === 0) {
return []; // No orders found in the date range
}
$orders = [];
while ($row = $result->fetch_assoc()) {
$tmp = [
'id' => (int)$row['id'],
'reg_1' => (string)$row['reg_1'],
'created_at' => (string)$row['created_at'],
];
// Add the order to the list
$orders[$tmp['reg_1']][] = $tmp;
}
// Filter out orders with more than one entry (possible duplicates)
// More than one order with the same reg_1, consider it a possible duplicate
$possibleDuplicates = array_filter($orders, function ($orderList) {
return count($orderList) > 1; // Keep only those with more than one order
});
if (empty($possibleDuplicates)) {
return []; // No possible duplicates found
}
// Loop through the possible duplicates and check if they are within 24 hours of each other
foreach ( $possibleDuplicates as $reg_1 => $orderList ) {
// Sort the orders by created_at date
usort($orderList, function ($a, $b) {
return strtotime($a['created_at']) - strtotime($b['created_at']);
});
// Check if any two orders are within 24 hours of each other
for ( $i = 0; $i < count($orderList) - 1; $i++ ) {
$firstOrder = $orderList[$i];
$secondOrder = $orderList[$i + 1];
if (strtotime($secondOrder['created_at']) - strtotime($firstOrder['created_at']) <= 86400) { // 86400 seconds in a day
// Mark them as possible duplicates
$possibleDuplicates[$reg_1][$i]['is_duplicate'] = true;
$possibleDuplicates[$reg_1][$i + 1]['is_duplicate'] = true;
}
}
}
// Return the possible duplicates orders_o objects
$resultOrders = [];
foreach ( $possibleDuplicates as $reg_1 => $orderList ) {
foreach ( $orderList as $order ) {
// Create a new orders_o object and select the order by id
$orderObject = new orders_o();
$orderObject->select((int)$order['id']);
// Add the order object to the result
$resultOrders[] = $orderObject;
}
}
return $resultOrders;
}
}
@@ -4,7 +4,6 @@ namespace routes;
use classes\authentication;
use Exception;
use objects\customer_vehicles_o;
use objects\logs_o;
use objects\orders_o;
use objects\users_o;
@@ -38,21 +37,6 @@ class InvoicingPeriodRoute
$dateTo = date('Y-m-d', strtotime($dateTo . ' +1 day'));
// Get the invoicing period for the user
$response->success([...self::getInvoicingPeriod($dateFrom, $dateTo)]);
// Log the incident
(new logs_o())->add('invoicing_period', 'global', 1, $user->id, 'GET_INVOICING_PERIOD', 'Successfully retrieved invoicing period');
$response->success(
$vehicles_o->listObjectsWithPaginationIfSet(
function ($vehicle) use ($user) {
// Return the object as an array
return [
...(new customer_vehicles_o())->select($vehicle['id'])->asArray(),
];
},
$vehicles_o->forceRestrictFilters([
...$restrict ?? []
])
)
);
} else {
// Log the incident
(new logs_o())->add('vehicles', 'global', 1, 0, 'LIST_OWN_VEHICLES', 'No user found, or invalid session');
@@ -81,6 +65,7 @@ class InvoicingPeriodRoute
'tank_cleaning' => self::getTankCleaning($dateFrom, $dateTo, $customersWithTransactions),
'special_arrangements' => self::getSpecialArrangements($dateFrom, $dateTo, $customersWithTransactions),
'invoice_per_order' => self::getInvoicingPerOrder($dateFrom, $dateTo, $customersWithTransactions),
'possible_duplicates' => self::getPossibleDuplicates($dateFrom, $dateTo, $customersWithTransactions),
'all' => $customersWithTransactions,
],
];
@@ -358,4 +343,40 @@ class InvoicingPeriodRoute
}
return $invoicing_per_order;
}
/**
* @throws Exception
*/
private static function getPossibleDuplicates(string $dateFrom, string $dateTo, array $customersWithTransactions = null): array
{
// If customersWithTransactions is not provided, get all customers with transactions in the specified date range
if ($customersWithTransactions === null) {
$customersWithTransactions = self::getCustomersWithTransactions($dateFrom, $dateTo);
}
// Get orders with the same reg_1, that has been created within 24 hours of each other
$orders = (new orders_o())->getOrdersWithPossibleDuplicates($dateFrom, $dateTo);
// Get the customer numbers from the orders
$customer_numbers = array_map(function ($order) {
return (int)$order->customer_id->value();
}, $orders);
// Remove duplicates from the customer numbers
$customer_numbers = array_unique($customer_numbers);
$possible_duplicates = [];
/** @var int $customer_number */
foreach ( $customer_numbers as $customer_number ) {
$possible_duplicate = self::getCustomerFromList((int)$customer_number, $customersWithTransactions);
// Set the requires_action to true, as these are potential duplicates
$possible_duplicate['requires_action'] = true;
$possible_duplicate['transactions'] = [];
// Add the transactions to the possible duplicate
foreach ( $orders as $order ) {
if ((int)$order->customer_id->value() === $customer_number) {
$possible_duplicate['transactions'][] = self::constructTransactionObject($order);
}
}
// Add the possible duplicate to the list
$possible_duplicates[] = $possible_duplicate;
}
return $possible_duplicates;
}
}