Merge pull request #63 from copenhagentruckwash/limble-module

limble-module
This commit is contained in:
Jeppe B
2025-06-26 14:33:10 +02:00
committed by GitHub
24 changed files with 439 additions and 87 deletions
@@ -5,6 +5,7 @@ require_once WD . '/modules/limble/interfaces/limble_endpoints_i.php';
require_once WD . '/modules/limble/classes/limble_request.php';
use Exception;
use limble\helpers\limble_tasks_pagination;
use limble_endpoints_i;
abstract class limble_endpoints extends limble_request implements limble_endpoints_i
@@ -14,14 +15,11 @@ abstract class limble_endpoints extends limble_request implements limble_endpoin
* @inheritDoc
* @throws Exception If the module is not enabled
*/
public function listTasks(): array
public function listTasks(limble_tasks_pagination $pagination): array
{
$this->requireModuleEnabled();
$url = $this->config->api_url . '/tasks';
$params = [
// 'status' => 'open',
// 'limit' => 100,
];
$params = [...$pagination->getParams()];
return $this->sendRequest(
$url,
'GET',
@@ -51,6 +49,22 @@ abstract class limble_endpoints extends limble_request implements limble_endpoin
);
}
/**
* @inheritDoc
* @throws Exception If the module is not enabled
*/
public function getTaskInstructions(int $taskId): array
{
$this->requireModuleEnabled();
$url = $this->config->api_url . '/tasks/' . $taskId . '/instructions';
return $this->sendRequest(
$url,
'GET',
[],
[self::getAuthHeader(), 'Content-Type: application/json']
);
}
/**
* @inheritDoc
* @throws Exception If the module is not enabled
@@ -59,12 +73,14 @@ abstract class limble_endpoints extends limble_request implements limble_endpoin
{
$this->requireModuleEnabled();
$url = $this->config->api_url . '/tasks';
// Set the taskId as a pagination parameter
$pagination = new limble_tasks_pagination();
$pagination->tasks = $taskId;
$pagination->limit = 1; // Limit to 1 task
return $this->sendRequest(
$url,
'GET',
[
'cursor' => $taskId,
],
[...$pagination->getParams()],
[self::getAuthHeader(), 'Content-Type: application/json']
);
}
@@ -0,0 +1,8 @@
<?php
namespace limble\helpers;
class limble_object_helper
{
}
@@ -0,0 +1,24 @@
<?php
namespace limble\helpers;
abstract class limble_pagination_helper
{
/**
* Limit of items per page.
* @var int $limit
*/
public int $limit = 100;
/**
* Page number to display.
* @var int $page
*/
public int $page = 1;
public function getParams(): array
{
return array_filter((array)$this, function ($value) {
return is_int($value) || is_string($value);
});
}
}
@@ -0,0 +1,42 @@
<?php
namespace limble\helpers;
class limble_task_comment extends limble_object_helper
{
/**
* The unique identifier for the comment.
* @var int $commentID
*/
public int $commentID;
/**
* The content of the comment.
* @var string $comment
*/
public string $comment;
/**
* An array of files associated with the comment.
* @var array $commentFiles
*/
public array $commentFiles;
/**
* The timestamp when the comment was created.
* @var int $timestamp
*/
public int $timestamp;
/**
* The unique identifier for the user who created the comment.
* @var int $userID
*/
public int $userID;
/**
* The email address associated with the comment, if any.
* @var string|null $commentEmailAddress
*/
public ?string $commentEmailAddress;
/**
* Indicates whether the comment should be shown to external users.
* @var bool $showExternalUsers
*/
public bool $showExternalUsers;
}
@@ -0,0 +1,47 @@
<?php
namespace limble\helpers;
class limble_task_instruction extends limble_object_helper
{
/**
* The unique identifier for the instruction.
* @var int $instructionID
*/
public int $instructionID;
/**
* The unique identifier for the task associated with this instruction.
* @var int $taskID
*/
public int $taskID;
/**
* The unique identifier for the parent instruction, if any.
* @var int $parentInstructionID
*/
public int $parentInstructionID;
/**
* The instruction text that describes what needs to be done.
* @var string $instruction
*/
public string $instruction;
/**
* The type of instruction, represented as an integer.
* @var int $type
*/
public int $type;
/**
* An array of options related to the instruction.
* @var array $options
*/
public array $options;
/**
* Indicates whether a response is required for this instruction.
* @var bool $response
*/
public bool $response;
/**
* An array of files associated with the instruction.
* @var array $instructionFiles
*/
public array $instructionFiles;
}
@@ -0,0 +1,14 @@
<?php
namespace limble\helpers;
class limble_tasks_pagination extends limble_pagination_helper
{
/**
* The unique identifier for the task.
* @note This is used to specify a specific task when retrieving pagination data.
* @see limble_task::taskID
* @var int $tasks
*/
public int $tasks;
}
@@ -53,26 +53,26 @@ class limble_webhook_payload_task extends limble_webhook_payload
public function __construct(array $payload)
{
parent::__construct($payload);
$this->slack->send_message('Initializing Limble Webhook Payload Task', 'Limble Webhook Task Initialization');
$this->taskID = (int)($payload['taskID'] ?? 0);
$this->status = (string)($payload['status'] ?? '');
$this->category = (string)($payload['category'] ?? '');
$this->user = (string)($payload['user'] ?? '');
$this->taskObject = new limble_task(((new limble())->getTask($payload['taskID'])) ?: []);
$this->slack->send_message('Task has been initialized with ID: ' . $this->taskID, 'Limble Webhook Task Initialized');
$this->taskObject = new limble_task(((new limble())->getTask($payload['taskID']))[0] ?? []);
$this->notifyWebhook();
}
protected function notifyWebhook(): void
{
// Generate the message to notify the webhook
$message = "";
$message .= "Task ID: " . $this->taskID . "\n";
$message .= "Name: " . $this->taskObject->name . "\n";
$message .= "Description: " . $this->taskObject->description . "\n";
$message .= "User: " . $this->user . "\n";
$message .= "Status: " . $this->status . "\n";
$message .= "Category: " . $this->category . "\n";
// Notify the webhook with the task object
$this->slack->send_message('
Task ID: ' . $this->taskID . '
Status: ' . $this->status . '
Category: ' . $this->category . '
User: ' . $this->user,
'Limble Webhook Notification'
);
$this->slack->send_message($message, 'Limble Webhook Task Notification');
}
/**
@@ -1,14 +1,18 @@
<?php
use limble\helpers\limble_task_instruction;
use limble\helpers\limble_tasks_pagination;
interface limble_endpoints_i
{
/**
* Get the tasks from the limble API
* @param limble_tasks_pagination $pagination
* @return array
*/
public function listTasks(): array;
public function listTasks(limble_tasks_pagination $pagination): array;
/**
* Get a specific task from the limble API
@@ -17,6 +21,14 @@ interface limble_endpoints_i
*/
public function getTask(int $taskId): array;
/**
* Get the list of task instructions from the limble API
* @param int $taskId
* @return limble_task_instruction[]
* @see limble_task_instruction
*/
public function getTaskInstructions(int $taskId): array;
/**
* Get the auth header for the API
@@ -1,7 +1,10 @@
<?php
namespace limble;
require_once WD . '/modules/limble/helpers/limble_object_helper.php';
require_once WD . '/modules/limble/helpers/limble_pagination_helper.php';
require_once WD . '/modules/limble/helpers/limble_tasks_pagination.php';
require_once WD . '/modules/limble/helpers/limble_task_instruction.php';
require_once WD . '/modules/limble/helpers/limble_task.php';
require_once WD . '/modules/limble/helpers/limble_tasks.php';
require_once WD . '/modules/limble/helpers/limble_webhook_payload.php';
@@ -0,0 +1,28 @@
<?php
namespace helpers;
use Exception;
use objects\products_o;
class xlvask_parser_h_nger extends xlvask_product_parser
{
use xlvask_product_parser_t;
public function __construct()
{
$this->setup('Hænger');
}
/**
* @inheritDoc
* @throws Exception
*/
protected function parse(xlvask_wash_item $wash_item, xlvask_usage_log $xlvask_usage_log): products_o
{
// For some reason, in XLVask the primary product is stored as vask_h_nger in some cases,
// This is a workaround to handle that case. (Since the functionality is exactly the same as // xlvask_parser_stor_bil)
return (new xlvask_parser_stor_bil())->parseProduct(...func_get_args());
}
}
@@ -11,7 +11,7 @@ class xlvask_parser_vask_udf_rt extends xlvask_product_parser
public function __construct()
{
$this->setup('vask_udf_rt');
$this->setup('Vask udført');
}
@@ -8,6 +8,7 @@ abstract class xlvask_product_parser
{
use xlvask_product_parser_t;
/**
* The setup method initializes the Original Product Name.
* This is required for the parser to function correctly.
@@ -8,6 +8,20 @@ use objects\products_o;
trait xlvask_product_parser_t
{
protected string $OriginalProductName;
/**
* This property indicates whether the parser is dynamic.
* When set to true, the parser will handle dynamic pricing.
* This should be set to true if the pricing of the product can change based on certain conditions,
* such as the amount of usage, time of day, or other factors.
* When this is set to true, the parser should implement logic to handle dynamic pricing.
* @example
* The "flowmeter" product parser uses this to calculate the price based on the amount of water used.
* * @note This is used to determine whether the parser should calculate a dynamic price or a static price.
* @see xlvask_product_parser_t::calculateDynamicPrice()
* When this is set to false, the parser should return a static price. (amount x price per unit)
* @var bool $useDynamicPricing
*/
protected bool $useDynamicPricing = false;
/**
@@ -40,5 +54,4 @@ trait xlvask_product_parser_t
*/
abstract protected function parse(xlvask_wash_item $wash_item, xlvask_usage_log $xlvask_usage_log): products_o;
}
@@ -312,6 +312,7 @@ class xlvask_usage_log extends xlvask_helper
'Stor bil',
'Lille bil',
'Vask udført',
'Hænger',
];
usort($generatedItems, function ($a, $b) use ($primaryItems) {
// Check if the item is a primary item
@@ -362,7 +363,7 @@ class xlvask_usage_log extends xlvask_helper
// Check if the parameter is empty or matches the default values
return $param === null || $param === '' || $param === $this->default_string || $param === $this->default_int || $param === $this->default_bool || $param === $this->default_int_nullable || $param === $this->default_string_nullable || $param === $this->default_bool_nullable;
}
/**
* Get the formatted date of the wash start time.
@@ -73,7 +73,7 @@ class xlvask_vehicles extends xlvask_helper
$xlvask = new xlvask();
$xlvask_cache = $xlvask->getCache();
if ($xlvask_cache->isVehicleCached($registrationNumber)) {
//return $xlvask_cache->getVehicleCache($registrationNumber);
return $xlvask_cache->getVehicleCache($registrationNumber);
} else if ($onlyCache) {
return null; // Return null if onlyCache is true and vehicle is not cached
}
@@ -229,7 +229,7 @@ class xlvask_wash_item extends xlvask_helper
// Check if the parameter is empty or matches the default values
return $param === null || $param === '' || $param === $this->default_string || $param === $this->default_int || $param === $this->default_bool || $param === $this->default_int_nullable || $param === $this->default_string_nullable || $param === $this->default_bool_nullable;
}
/**
* Get the product associated with this wash item.
@@ -352,4 +352,10 @@ class xlvask_wash_item extends xlvask_helper
// If either PriceIncVat or Count is not numeric, return 0
return 0.0;
}
public function getUnitPriceExVat(): float
{
// Calculate the unit price excluding VAT
return $this->getPriceExVat() / (float)$this->Count;
}
}
@@ -49,6 +49,7 @@ require_once WD . '/modules/xlvask/helpers/xlvask_parser_specials_be_sider.php';
require_once WD . '/modules/xlvask/helpers/xlvask_parser_ikke_ht_dysebom_p_tag.php';
require_once WD . '/modules/xlvask/helpers/xlvask_parser_ht_osc_sider.php';
require_once WD . '/modules/xlvask/helpers/xlvask_parser_kun_b_rster_ved_hytten.php';
require_once WD . '/modules/xlvask/helpers/xlvask_parser_h_nger.php';
use helpers\xlvask_cache;
use helpers\xlvask_create_customer;
@@ -90,10 +90,19 @@ class collected_order_invoices_o extends db
}
/**
* Get the invoice collection as an array
* @throws ApiErrorException If the payment method is Stripe and the request fails
* @throws Exception If the request was not successful
*/
public function asArray(): array
{
// Require the invoice collection to be selected
self::requireSelected();
// Check if the object is cached
$cached = self::getCached('asArray', $this->id);
if ($cached !== null) {
return (array)$cached;
}
$tmp = [
'id' => (int)$this->id,
'customer_number' => (int)$this->customer_number->value(),
@@ -130,6 +139,9 @@ class collected_order_invoices_o extends db
]);
$tmp['stripe'] = $stripe_details;
}
// Cache the result
self::cache('asArray', $tmp, $this->id);
self::setCachedExpiration('asArray', self::$asArrayCacheExpiration, $this->id);
return $tmp;
}
@@ -141,6 +153,8 @@ class collected_order_invoices_o extends db
*/
public function getOrders(bool $count = false): array|int
{
// Require the invoice collection to be selected
self::requireSelected();
$orders = new orders_o();
$order_ids = $orders->getFieldsWhere(
[
@@ -542,7 +556,8 @@ class collected_order_invoices_o extends db
public function objectChanged(): void
{
//TODO: Add cache invalidation
// Invalidate the cache, so the next time the object is requested, it will be fetched from the database
self::deleteCached('asArray', $this->id);
}
/**
@@ -609,6 +624,8 @@ class collected_order_invoices_o extends db
foreach ( $orders as $order ) {
self::addInvoiceToDraft($order['id'], true, $draft_id, $currency);
}
// Object changed
self::objectChanged();
return $this;
}
@@ -837,6 +854,8 @@ class collected_order_invoices_o extends db
// Set the order to the new invoice collection
$order_object->invoice_collection_id->set($tmp->id);
}
// Invalidate the cache for the invoice collection
$this->objectChanged();
}
/**
@@ -912,6 +931,7 @@ class collected_order_invoices_o extends db
$transaction->invoice_collection_id->set($this->id);
$transaction->created_at->set(self::getFirstDayOfMonth($this->created_at->value()));
$transaction->objectChanged();
$this->objectChanged();
// Add the vehicle subscriptions to the transaction
$order_items_o = new order_items_o();
foreach ( $vehicle_array as $vehicle ) {
@@ -974,6 +994,7 @@ class collected_order_invoices_o extends db
$order_item_object->requireSelected();
$order_item_object->include_in_invoice->set(0);
$order_item_object->price->set((int)self::getWashSubscriptionPrice((new products_o())->select((int)$order_item['product_id'])->price->value()) / 2);
$order_item_object->objectChanged();
}
// Check if the order item product id is equal any of the vehicle subscription addons product id
if (isset($vehicle_regs[$order['reg_1']]['addons'][$order_item['product_id']])) {
@@ -999,10 +1020,13 @@ class collected_order_invoices_o extends db
$order_item_object->requireSelected();
$order_item_object->include_in_invoice->set(0);
$order_item_object->price->set($tmp_subscription_price);
$order_item_object->objectChanged();
}
}
$order_object->objectChanged();
}
}
$this->objectChanged();
//print_r($vehicle_array);
}
@@ -1034,6 +1058,8 @@ class collected_order_invoices_o extends db
$order->requireSelected();
$order->delete();
}
// Clear the cache for the invoice collection
$this->objectChanged();
}
private static function getFirstDayOfMonth(string $timestamp): string
@@ -1137,7 +1163,10 @@ class collected_order_invoices_o extends db
$order_item_object->requireSelected();
$order_item_object->include_in_invoice->set(0);
$order_item_object->price->set(0);
$order_item_object->objectChanged();
}
}
// Invalidate the cache for the invoice collection
$this->objectChanged();
}
}
@@ -43,6 +43,11 @@ class customer_vehicles_o extends db
public function asArray(): array
{
self::requireSelected();
// Check if the vehicle is cached
$cached = $this->getCached('asArray', $this->id);
if ($cached) {
return (array)$cached;
}
$wash_subscription = (bool)$this->wash_subscription->value();
$addons = self::transformObjectsToArray(
self::getAddons()
@@ -53,7 +58,7 @@ class customer_vehicles_o extends db
$last_order_id = self::getLastOrderId();
$customer_number = (int)$this->customer_id->value();
$xlvask = $this->hasXLVask() ? $this->getXLVask() : null;
return [
$tmp = [
'id' => (int)$this->id,
'user_id' => (int)(new users_o())->getUserIdFromEconomic((int)$customer_number),
'customer_id' => (int)$this->customer_id->value(),
@@ -74,6 +79,10 @@ class customer_vehicles_o extends db
return $vehicle_type->toArray();
}, $this->getVehicleTypes()),
];
// Cache the result
$this->cache('asArray', $tmp, $this->id);
$this->setCachedExpiration('asArray', self::$asArrayCacheExpiration, $this->id);
return $tmp;
}
/**
@@ -237,7 +246,8 @@ class customer_vehicles_o extends db
public function objectChanged(): void
{
// Since the customer_vehicles object is not cached, there is no need to invalidate the cache
// Clear the cache for the object
$this->deleteCached('asArray', $this->id);
}
public function structure(): void
@@ -245,6 +255,11 @@ class customer_vehicles_o extends db
$this->setTable('customer_vehicles');
}
public function delete()
{
}
public function getObjectProperties(): void
{
$this->customer_id = new object_property($this->table, $this->id, 'customer_id', 'int', true);
@@ -345,6 +360,7 @@ class customer_vehicles_o extends db
$xlvask->updateVehicle($xlvask_vehicle);
// Cache the updated vehicle
$xlvask->getCache()->setVehicleCache($xlvask_vehicle->registrationNumber, $xlvask_vehicle);
$this->objectChanged();
}
/**
@@ -393,6 +409,7 @@ class customer_vehicles_o extends db
/** @var xlvask_vehicles $vehicles */
$xlvask_vehicle = $vehicles::getVehicleByRegistrationNumber((string)$this->reg->value());
$xlvask->getCache()->setVehicleCache($xlvask_vehicle->registrationNumber, $xlvask_vehicle);
$this->objectChanged();
return $xlvask_vehicle;
}
@@ -429,5 +446,6 @@ class customer_vehicles_o extends db
$xlvask->updateVehicle($xlvask_vehicle);
// Cache the updated vehicle
$xlvask->getCache()->setVehicleCache($xlvask_vehicle->registrationNumber, $xlvask_vehicle);
$this->objectChanged();
}
}
+40 -9
View File
@@ -4,6 +4,7 @@ namespace objects;
use classes\db;
use classes\object_property;
use Exception;
use traits\db_object_t;
class order_items_o extends db
@@ -62,11 +63,6 @@ class order_items_o extends db
$this->setTable('order_items');
}
public function objectChanged(): void
{
// No need to invalidate the cache, since the order_items object is not cached
}
public function getOrderItemById(int $id): order_items_o
{
global $db;
@@ -113,11 +109,37 @@ class order_items_o extends db
if ($related_item_id) {
$this->related_item_id->set($related_item_id);
}
} catch (\Exception $e) {
// Inform the order object that a new item has been added
$this->getOrder()->objectChanged();
} catch (Exception $e) {
$response->error($e->getMessage());
}
}
/**
* @throws Exception
*/
public function objectChanged(): void
{
// This method is called when the object is changed, to inform the order object
// that an item has been added, edited or removed.
// This is used to update the order total and other related properties.
$order = $this->getOrder();
$order->objectChanged();
}
/**
* Get the order object associated with this order item
* @return orders_o The order object associated with this order item
* @throws Exception If the order item is not selected
* @throws Exception If no order is selected
*/
public function getOrder(): orders_o
{
self::requireSelected();
return (new orders_o())->select($this->id);
}
public function edit(int $id, int $order_id, int $product_id, string $reference, string $notes, int $cashier_id, int $price, int $quantity): void
{
global $db, $response;
@@ -132,7 +154,9 @@ class order_items_o extends db
// Set the values of the object properties
$this->getObjectProperties();
} catch (\Exception $e) {
// Inform the order object that an item has been edited
$this->objectChanged();
} catch (Exception $e) {
$response->error($e->getMessage());
}
}
@@ -173,13 +197,17 @@ class order_items_o extends db
if ($notes) {
$this->notes->set($notes);
}
$this->objectChanged();
} catch (\Exception $e) {
} catch (Exception $e) {
$response->error($e->getMessage());
}
}
/**
* @throws Exception
*/
public function removeOrderItem(int $id): void
{
// TODO: Implement delete() method instead
@@ -187,6 +215,8 @@ class order_items_o extends db
$this->id = $id;
$sql = "DELETE FROM $this->table WHERE id = $this->id or related_item_id = $this->id";
$db->query($sql);
// Inform the order object that an item has been removed
$this->getOrder()->objectChanged();
}
public function getItemAsArray(): array
@@ -236,7 +266,8 @@ class order_items_o extends db
$db->query($sql);
// Set the values of the object properties
$this->getObjectProperties();
} catch (\Exception $e) {
$this->objectChanged();
} catch (Exception $e) {
$response->error($e->getMessage());
}
}
+62 -35
View File
@@ -34,6 +34,7 @@ class orders_o extends db
public object_property $wash_id; // The XL Vask Wash ID, if any
public object_property $lane; // The lane used for the order, if any
public function structure(): void
{
$this->setTable('orders');
@@ -116,9 +117,49 @@ class orders_o extends db
{
// Set the deleted_at property to the current timestamp
$this->deleted_at->set(date('Y-m-d H:i:s'));
$this->objectChanged();
// Save the object
}
/**
* @throws Exception If the order is not selected
* This function is called when the order object is changed.
*/
public function objectChanged(): void
{
self::requireSelected();
// Reset the cached object
self::deleteCached('asArray', $this->id);
// Inform the order collection that the order has changed
$this->getOrderCollection()->objectChanged();
}
/**
* Get the order collection for the order
* @return collected_order_invoices_o The order collection
* @throws Exception If the order is not selected
*/
public function getOrderCollection(): collected_order_invoices_o
{
self::requireSelected();
$order_collection = new collected_order_invoices_o();
$order_collection->select($this->invoice_collection_id->value());
if (!$order_collection->exists()) {
throw new Exception('Order collection not found');
}
return $order_collection;
}
public function exists(): bool
{
// Check if the id is greater than 0, and that the deleted_at property is null
if ($this->id > 0) {
$this->getObjectProperties();
return $this->deleted_at->value() === null;
}
return false;
}
public function restore(): void
{
// Set the deleted_at property to null
@@ -192,16 +233,6 @@ class orders_o extends db
$this->{$data['field']}->set($data['value']);
}
public function exists(): bool
{
// Check if the id is greater than 0, and that the deleted_at property is null
if ($this->id > 0) {
$this->getObjectProperties();
return $this->deleted_at->value() === null;
}
return false;
}
/**
* Mark the order as completed
* @throws Exception If the order is not selected
@@ -223,11 +254,6 @@ class orders_o extends db
$this->objectChanged();
}
public function objectChanged(): void
{
// Since the orders object is not cached, there is no need to invalidate the cache
}
/**
* Get the order by invoice id
* @param int $invoiceId
@@ -427,22 +453,6 @@ class orders_o extends db
return $count;
}
/**
* Get the order collection for the order
* @return collected_order_invoices_o The order collection
* @throws Exception If the order is not selected
*/
public function getOrderCollection(): collected_order_invoices_o
{
self::requireSelected();
$order_collection = new collected_order_invoices_o();
$order_collection->select($this->invoice_collection_id->value());
if (!$order_collection->exists()) {
throw new Exception('Order collection not found');
}
return $order_collection;
}
/**
* Get the wash subscription transactions for a customer
* @throws Exception If something goes wrong
@@ -473,9 +483,22 @@ class orders_o extends db
);
}
public function asArray(): array
/**
* @return array The order as an array
* @throws Exception
* Convert the order object to an array
*/
public function asArray(bool $skipCache = false): array
{
return [
self::requireSelected();
if (!$skipCache) {
// Check if the object is cached
$cached = self::getCached('asArray', $this->id);
if ($cached) {
return (array)$cached;
}
}
$tmp = [
'id' => $this->id,
'customer_id' => (int)$this->customer_id->value(),
'cashier_id' => (int)$this->cashier_id->value(),
@@ -495,6 +518,10 @@ class orders_o extends db
'lane' => $this->lane->value(),
'closed_at' => (int)$this->invoice_collection_id->value() ? (new collected_order_invoices_o())->select((int)$this->invoice_collection_id->value())->closed_at->value() : null,
];
// Cache the object
self::cache('asArray', $tmp, $this->id);
self::setCachedExpiration('asArray', self::$asArrayCacheExpiration, $this->id);
return $tmp;
}
public function getNetAmount(): float
@@ -754,8 +781,8 @@ class orders_o extends db
'',
'', //$washItem->OriginalProductName,
2285,
$washItem->getPriceExVat(),
$washItem->Count,
(int)$washItem->getUnitPriceExVat(),
(int)$washItem->Count,
$firstItemId === null ? null : $firstItemId, // Set the first item as the parent item (if applicable)
);
// Set the first item ID for the next item to link to (provided this is the first item)
@@ -6,6 +6,7 @@ use classes\limble;
use classes\response;
use classes\router;
use classes\slack;
use limble\helpers\limble_tasks_pagination;
use limble\helpers\limble_webhook_payload_task;
use traits\route_t;
@@ -21,7 +22,6 @@ class moduleLimbleRoute
$this->post('/modules/limble/webhook/task', function () {
global $response;
$slack = new slack();
$slack->send_message('Limble Webhook Task Triggered', 'Limble Webhook');
//TODO: Add authentication of some sort here
//self::requirePermission('modules_limble_webhooks_task');
// Check if the module is enabled
@@ -32,14 +32,7 @@ class moduleLimbleRoute
if (json_last_error() !== JSON_ERROR_NONE) {
$response->error('Invalid JSON payload', 400);
}
$slack->send_message('TaskId: ' . ($payload['taskID'] ?? 'Not provided'), 'Limble Webhook Task ID');
$slack->send_message('Payload: ' . json_encode($payload), 'Limble Webhook Task Payload');
$task = new limble_webhook_payload_task($payload);
//$task = new $limble->helpers->limble_webhook_payload_task($payload);
$slack->send_message('Limble Webhook Task Received: ' . $task->taskID, 'Limble Webhook Task');
$slack->send_message('Task Name: ' . $task->taskObject->name, 'Limble Webhook Task Name');
// $slack->send_message('Task ID: ' . $payload['task_id'], 'Limble Webhook Task ID');
// Response
$response->success('Debug', 200);
},
@@ -56,8 +49,10 @@ class moduleLimbleRoute
// Check if the module is enabled
$limble = new limble();
$limble->requireModuleEnabled();
$pagination = new limble_tasks_pagination();
//$pagination->tasks = 2;
// Get the tasks
$tasks = $limble->getTasks()->formatTasks($limble->listTasks());
$tasks = $limble->getTasks()->formatTasks($limble->listTasks($pagination));
// Response
$response->success($tasks, 200);
},
+3 -2
View File
@@ -41,7 +41,7 @@ class ordersRoute
// Log the incident
(new logs_o())->add('orders', 'global', 1, $user->id, 'LIST_ORDERS', 'Successfully listed orders');
// Create economic_module_orders object
$economic_module_orders = new economic_module_orders();
//$economic_module_orders = new economic_module_orders();
$orders = new orders_o();
if (!$restrict_only_own) {
$department_ids = $user->getGroup()->getDepartments();
@@ -216,7 +216,8 @@ class ordersRoute
if (isset($data['created_at'])) {
$order->created_at->set($data['created_at']);
}
// If the department ID is set, validate it
// Void any cached key for the order
$order->objectChanged();
// Log the incident
(new logs_o())->add('orders', $order->department_id->value(), 1, $user->id, 'EDIT_ORDER', 'Successfully updated an order (ID: ' . $data['id'] . ')');
// Return a success message
+39 -4
View File
@@ -44,10 +44,11 @@ use objects\users_o;
trait db_object_t
{
public int $id; // The id of the object in the database
private string $table; // The table of the objects in the database (e.g. users)
private array $searchableFields = []; // The fields to search in the database (e.g. ['name', 'email']). If empty, all fields will be searched
private array $whereClauses = []; // The where clauses to add to the pagination query
public static int $asArrayCacheExpiration = 600; // The id of the object in the database
public int $id; // The table of the objects in the database (e.g. users)
private string $table; // The fields to search in the database (e.g. ['name', 'email']). If empty, all fields will be searched
private array $searchableFields = []; // The where clauses to add to the pagination query
private array $whereClauses = []; // The cache expiration time for the asArray function, in seconds. This is used to cache the result of the asArray function to improve performance. Default is 10 minutes (600 seconds).
public function __construct()
{
@@ -744,6 +745,40 @@ trait db_object_t
redis->set($this->table . '_' . $objectId . '_' . $key, $data);
}
/**
* Set cached object expiration time
* @param string $key The key to set the cached object expiration time
* @param int $seconds The number of seconds to set the cached object expiration time
* @param null $objectId
* @return void
*/
public function setCachedExpiration(string $key, int $seconds, $objectId = null): void
{
// If the object id is not set, use the object id
if (!$objectId) {
$objectId = $this->id;
}
// Set the expiration time for the cached data
redis->expire($this->table . '_' . $objectId . '_' . $key, $seconds);
}
/**
* Get a cached object key (redis key)
* @param string $key The key to get the cached object
* @return string The cached object key
* @throws Exception If the object is not selected, it throws an exception
*/
public function getCachedKey(string $key, $objectId = null): string
{
self::requireSelected();
// If the object id is not set, use the object id
if (!$objectId) {
$objectId = $this->id;
}
// Return the cached data key
return $this->table . '_' . $objectId . '_' . $key;
}
/**
* Get cached object
* @param string $key The key to get the cached object