334 lines
15 KiB
PHP
334 lines
15 KiB
PHP
<?php
|
|
|
|
namespace helpers;
|
|
|
|
use Exception;
|
|
use objects\orders_o;
|
|
use objects\users_o;
|
|
|
|
class xlvask_tasks
|
|
{
|
|
public function __construct()
|
|
{
|
|
// Define the error messages if they are not already defined
|
|
/**
|
|
* if (!defined("ERROR_MESSAGE_ECONOMIC_INVOICE_NOT_FOUND")) {
|
|
* define("ERROR_MESSAGE_ECONOMIC_INVOICE_NOT_FOUND", 'ECONOMIC_INVOICE_NOT_FOUND');
|
|
* }
|
|
* if (!defined("ERROR_MESSAGE_ECONOMIC_INVOICE_DRAFT_NOT_FOUND")) {
|
|
* define("ERROR_MESSAGE_ECONOMIC_INVOICE_DRAFT_NOT_FOUND", 'ECONOMIC_INVOICE_DRAFT_NOT_FOUND');
|
|
* }
|
|
*/
|
|
}
|
|
|
|
/**
|
|
* @throws Exception
|
|
*/
|
|
public function runCronTasks(): void
|
|
{
|
|
// Define the XL Vask object
|
|
$xlvask = new \classes\xlvask();
|
|
// Require the module to be enabled
|
|
$xlvask->requireModuleEnabled();
|
|
// Run the synchronization tasks
|
|
if ($xlvask->config->synchronization_enabled->isTrue()) {
|
|
// Synchronize users, this will keep the users (XL Vask customer objects) in cache up to date
|
|
$this->runSyncUsers(true);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Run the synchronize users task
|
|
* This task fetches the users from XL Vask, and synchronizes them with this system.
|
|
* This includes:
|
|
* - Fetching the users from XL Vask
|
|
* - Checking if the users exist in this system
|
|
* - Add objects to the cache, when a matching user is found.
|
|
* @return null|array['customers'] The customers fetched from XL Vask, null if synchronization is not enabled
|
|
* @throws Exception If the task fails
|
|
*/
|
|
public function runSyncUsers(bool $isSilent = false): array|null
|
|
{
|
|
// Define the XL Vask object
|
|
$xlvask = new \classes\xlvask();
|
|
// Require the module to be enabled
|
|
$xlvask->requireModuleEnabled();
|
|
// Check if synchronization is enabled
|
|
if (!$xlvask->config->synchronization_enabled->isTrue()) {
|
|
if (!$isSilent) {
|
|
throw new Exception('XL Vask synchronization is not enabled.');
|
|
}
|
|
return null; // Synchronization is not enabled, do nothing
|
|
}
|
|
// Get the users from XL Vask
|
|
$customer_objects = $this->fetchCustomers();
|
|
// Return the customers with an external ID
|
|
$customers = [
|
|
'with_external_id' => [...self::filterCustomersWithExternalId($customer_objects)],
|
|
'without_external_id' => [...self::filterCustomersWithoutExternalId($customer_objects)],
|
|
'all' => $customer_objects,
|
|
];
|
|
|
|
return self::synchronize_customers($customers['with_external_id']);
|
|
}
|
|
|
|
/**
|
|
* Get the customers registered in XL Vask
|
|
* This method fetches the customers from XL Vask and returns them as an array of customer objects.
|
|
* @return array[xlvask_customer] An array of customer objects fetched from XL Vask
|
|
* @throws Exception If the task fails
|
|
*/
|
|
public function fetchCustomers(): array
|
|
{
|
|
// Define the XL Vask object
|
|
$xlvask = new \classes\xlvask();
|
|
// Require the module to be enabled
|
|
$xlvask->requireModuleEnabled();
|
|
// Get the users from XL Vask
|
|
$customer_objects_raw = $xlvask->getCustomers();
|
|
// Parse the users into customer objects
|
|
return array_map(function ($customer) use ($xlvask) {
|
|
return (new $xlvask->helpers->xlvask_customer())->setProperties($customer);
|
|
}, $customer_objects_raw);
|
|
}
|
|
|
|
/**
|
|
* Get the customers with an external ID
|
|
* @param array $customers Customers to filter
|
|
* @return array The customers with an external ID
|
|
*/
|
|
public static function filterCustomersWithExternalId(array $customers): array
|
|
{
|
|
return array_filter($customers, function ($customer) {
|
|
/** @var xlvask_customer $customer */
|
|
return !empty($customer->externId);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Get the customers without an external ID
|
|
* @param array $customers Customers to filter
|
|
* @return array The customers without an external ID
|
|
*/
|
|
public static function filterCustomersWithoutExternalId(array $customers): array
|
|
{
|
|
return array_filter($customers, function ($customer) {
|
|
/** @var xlvask_customer $customer */
|
|
return empty($customer->externId);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Synchronize customers with external IDs
|
|
* This method synchronizes the customers with external IDs from XL Vask.
|
|
* It checks if the customers exist in this system, creates them if they do not exist,
|
|
* and adds/removes the associated external ID to the users in this system.
|
|
* @param array $with_external_id Customers with external IDs to synchronize
|
|
* @return array|null The synchronized customers, null if synchronization is not enabled
|
|
* @throws Exception
|
|
*/
|
|
private static function synchronize_customers(array $with_external_id): array|null
|
|
{
|
|
// Define the XL Vask object
|
|
$xlvask = new \classes\xlvask();
|
|
// Require the module to be enabled
|
|
$xlvask->requireModuleEnabled();
|
|
// Check if synchronization is enabled
|
|
if (!$xlvask->config->synchronization_enabled->isTrue()) {
|
|
return null; // Synchronization is not enabled, do nothing
|
|
}
|
|
|
|
// Get a list of customer numbers that we need to synchronize
|
|
$customer_numbers = array_map(function ($customer) {
|
|
/** @var xlvask_customer $customer */
|
|
return $customer->externId; // The customer number is stored in the externId property in XL Vask
|
|
}, $with_external_id);
|
|
|
|
// Get all the user ids associated with the customer numbers
|
|
$users = (new users_o())->getUsersByCustomerNumbers($customer_numbers, true);
|
|
|
|
$cache = $xlvask->getCache();
|
|
|
|
/** @var xlvask_customer $customer */
|
|
foreach ( $with_external_id as $customer ) {
|
|
// Check if the customer exists in this system
|
|
if (isset($users[$customer->externId])) {
|
|
// The user exists, update the user with the external ID
|
|
/** @var users_o $user */
|
|
$user = $users[$customer->externId];
|
|
// Cache the customer
|
|
$cache->setCustomerCache((int)$customer->externId, $customer);
|
|
} else {
|
|
//echo 'MISSING USER: ' . $customer->name . ' (' . $customer->externId . ')' . PHP_EOL;
|
|
}
|
|
}
|
|
return $with_external_id; // Return the synchronized customers
|
|
}
|
|
|
|
/**
|
|
* Run the sync usage task
|
|
* This task is used to synchronize the usage of the XL Vask module.
|
|
* It fetches the usage data from XL Vask and adds it to the applicable users.
|
|
* The time format XL vask uses is "2025-05-01T00:00:00.000" - this is the ISO 8601 format.
|
|
* @return array|null
|
|
* @throws Exception
|
|
*/
|
|
public function runSyncUsage(): array|null
|
|
{
|
|
// Define the XL Vask object
|
|
$xlvask = new \classes\xlvask();
|
|
// Require the module to be enabled
|
|
$xlvask->requireModuleEnabled();
|
|
// Check if synchronization is enabled
|
|
if (!$xlvask->config->synchronization_enabled->isTrue()) {
|
|
throw new Exception('XL Vask synchronization is not enabled.');
|
|
}
|
|
// Set the date from which to fetch the usage data
|
|
// Since this is a cron task, we will fetch the usage data from the last 24 hours
|
|
$minutes = 24 * 60; // 24 hours in minutes
|
|
$dateFrom = date('Y-m-d\TH:i:s.000', strtotime('-' . $minutes . ' minutes'));
|
|
echo $dateFrom;
|
|
|
|
|
|
// If there are no customers, get them. TODO: Remove this in production, this is just for testing
|
|
$xlvask->getTasks()->runSyncUsers(true);
|
|
|
|
// Get the cached customers
|
|
$customers = $xlvask->getCache()->getAllCachedCustomers();
|
|
|
|
// Loop through the customers and check if there's any new usage data
|
|
foreach ( $customers as $customer ) {
|
|
/** @var xlvask_customer $customer */
|
|
// Check if the customer has an externId
|
|
if (empty($customer->externId)) {
|
|
continue; // Skip customers without an externId
|
|
}
|
|
echo 'Checking customer: ' . $customer->name . ' (' . $customer->externId . ')' . PHP_EOL;
|
|
$tmp_usage_logs = self::formatUsageLogs($xlvask->getUsageLog(
|
|
$dateFrom,
|
|
null, // regNr
|
|
null, // vehicleId
|
|
$customer->customerId // customerId
|
|
));
|
|
foreach ( $tmp_usage_logs as $log ) {
|
|
/** @var xlvask_usage_log $log */
|
|
// Check if the wash was completed
|
|
if (!$log->isCompleted()) {
|
|
echo 'A log is not completed: ' . $log->getFormattedDate() . ' - ' . $log->CustomerId . ' - ' . $log->VehicleId . PHP_EOL;
|
|
continue; // Skip logs that are not completed
|
|
}
|
|
|
|
echo PHP_EOL;
|
|
echo '### ' . $log->getFormattedDate() . ' - ' . $customer->name . ' (' . $customer->externId . ') - ' . $log->getTotalPrice() . PHP_EOL;
|
|
echo '# License Plate: ' . $log->RegistrationNumber . PHP_EOL;
|
|
echo '# Vehicle ID: ' . $log->VehicleId . PHP_EOL;
|
|
echo '# Wash ID: ' . $log->WashId . PHP_EOL;
|
|
echo '# Hall: ' . $log->Hall . PHP_EOL;
|
|
echo '# Hall ID: ' . $log->HallId . PHP_EOL;
|
|
echo '# Department: ' . $log->getDepartment()->id . ' ( ' . $log->getDepartment()->name->value() . ' )' . PHP_EOL;
|
|
echo '# Track / Lane: ' . $log->getLane() . PHP_EOL;
|
|
echo '# Linked to order: ' . ($log->isLinkedToOrder() ? 'Yes' : 'No') . PHP_EOL;
|
|
echo '# Items: ' . PHP_EOL;
|
|
$tmp_skipped_items = [];
|
|
foreach ( $log->WashItems as $item ) {
|
|
/** @var xlvask_wash_item $item */
|
|
// Skip items that have the id 64, since these are not relevant to anyone.
|
|
$tmp_item_id = $item->getProduct($log)->id;
|
|
if ($tmp_item_id === 64 || !$item->isCountAboveZero()) {
|
|
$tmp_skipped_items[] = $item;
|
|
continue; // Skip items with id 64 (Or items simply not relevant)
|
|
}
|
|
echo '## ' . $item->Count . ' x ' . $item->OriginalProductName . ' @ ' . $item->getPriceExVat() . ' as ' . $tmp_item_id . ' ( ' . $item->getProduct($log)->name->value() . ' )' . PHP_EOL;
|
|
}
|
|
echo '### Total: ' . $log->getTotalPrice() . PHP_EOL;
|
|
echo '### Skipped items: ' . count($tmp_skipped_items) . PHP_EOL;
|
|
if (count($tmp_skipped_items) > 0) {
|
|
echo '### Skipped items details: ' . PHP_EOL;
|
|
foreach ( $tmp_skipped_items as $skipped_item ) {
|
|
/** @var xlvask_wash_item $skipped_item */
|
|
echo '## ' . $skipped_item->Count . ' x ' . $skipped_item->OriginalProductName . ' @ ' . $skipped_item->getPriceExVat() . ' as ' . $skipped_item->getProduct($log)->id . ' ( ' . $skipped_item->getProduct($log)->name->value() . ' )' . PHP_EOL;
|
|
}
|
|
}
|
|
echo '#' . PHP_EOL;
|
|
if (!$log->isLinkedToOrder()) {
|
|
echo '# Checking for orders that might be addressing this wash.' . PHP_EOL;
|
|
// Check if an order that matches this wash exists.
|
|
if ($log->getPotentialOrder() !== null) {
|
|
echo '# This wash might be associated with an order: ' . $log->getPotentialOrder()->id . PHP_EOL;
|
|
} else {
|
|
// If no order is found, we will generate a new order.
|
|
echo '# No potential order found for this wash.' . PHP_EOL;
|
|
// Verify the customer object
|
|
if (!$customer instanceof xlvask_customer) {
|
|
echo '# The customer object is not an instance of xlvask_customer.' . PHP_EOL;
|
|
continue; // Skip this wash
|
|
}
|
|
if (!$tmp_order = $this->createOrderFromWash($log, $customer)) {
|
|
echo '# Failed to create an order from this wash.' . PHP_EOL;
|
|
} else {
|
|
echo '# Order created successfully.' . PHP_EOL;
|
|
echo '# Order ID: ' . $tmp_order->id . PHP_EOL;
|
|
echo '# Order total: ' . $tmp_order->getNetAmount() . PHP_EOL;
|
|
}
|
|
}
|
|
echo '# This wash is not linked to an order, generating a new order.' . PHP_EOL;
|
|
}
|
|
echo '# ------------------------' . PHP_EOL;
|
|
}
|
|
//print_r($tmp_usage_logs);
|
|
// Check if the customer has any usage data in the last 24 hours
|
|
// This is a placeholder, you might want to implement a method to check this
|
|
// if (!$xlvask->hasRecentUsageData($customer->externId, $dateFrom)) {
|
|
// continue; // Skip customers without recent usage data
|
|
// }
|
|
}
|
|
|
|
// Process the usage data and update the users accordingly
|
|
//$xlvask->processUsageData($usage_data);
|
|
return [];
|
|
}
|
|
|
|
private static function formatUsageLogs(array $getUsageLog): array
|
|
{
|
|
//print_r($getUsageLog);
|
|
// Format the usage logs to a more readable format
|
|
// This is a placeholder, you might want to implement a method to format the logs
|
|
return array_map(/**
|
|
* @throws Exception
|
|
*/ function ($log) {
|
|
$xlvask = new \classes\xlvask();
|
|
return (new $xlvask->helpers->xlvask_usage_log())->setProperties($log);
|
|
}, $getUsageLog);
|
|
}
|
|
|
|
/**
|
|
* @throws Exception If the log is not completed, or if the customer does not have an externId, or if the customer does not exist in this system.
|
|
*/
|
|
public function createOrderFromWash(xlvask_usage_log $log, xlvask_customer|\stdClass $customer): ?orders_o
|
|
{
|
|
// Make sure the XL Vask module is enabled
|
|
$xlvask = new \classes\xlvask();
|
|
$xlvask->requireModuleEnabled();
|
|
|
|
// Check if the log is completed
|
|
if (!$log->isCompleted()) {
|
|
throw new Exception('The log ( ID: ' . $log->WashId . ' ) is not completed, cannot create an order from it.');
|
|
}
|
|
// Check if the customer has an externId
|
|
if (empty($customer->externId)) {
|
|
throw new Exception('The customer ( ID: ' . $customer->customerId . ' ) does not have an externId, cannot create an order from it.');
|
|
}
|
|
// Check if the customer exists in this system
|
|
if (!$tmp_user = $customer->getUser()) {
|
|
throw new Exception('The customer ( ID: ' . $customer->customerId . ' ) does not exist in this system, cannot create an order from it.');
|
|
}
|
|
// Create a new order object
|
|
$order = new orders_o();
|
|
$order->addXLVaskOrder(
|
|
$tmp_user,
|
|
$log,
|
|
);
|
|
// Return the order object
|
|
return $order;
|
|
}
|
|
} |