Add routes and objects for managing collected order invoices

Introduced GET and POST endpoints for collected order invoices, enabling listing and creation functionalities for authorized users. Added a new database object to handle invoice-related operations and validations. Included utility functions to enforce parameter requirements and data integrity.
This commit is contained in:
Jepp9350
2025-02-28 12:07:46 +01:00
parent 7497e0c744
commit 9bf0355e47
4 changed files with 289 additions and 0 deletions
@@ -0,0 +1,130 @@
<?php
namespace objects;
use classes\db;
use classes\object_property;
use Exception;
use traits\db_object_t;
class collected_order_invoices_o extends db
{
use db_object_t;
public object_property $customer_number;
public object_property $name;
public object_property $notes;
public object_property $processor;
public object_property $external_id;
public object_property $created_at;
public object_property $updated_at;
public object_property $closed_at;
public function structure(): void
{
$this->setTable('collected_order_invoices');
}
/**
* Create a new collected order invoice
* @param int $customer_number The E-conomic customer number
* @param string|null $name The name of the invoice (optional)
* @param string|null $notes The notes for the invoice (optional)
* @param int|null $processor The processor id (optional)
* @return self The created object
* @throws Exception If the object was not created successfully
*/
public function add(int $customer_number, ?string $name = null, ?string $notes = null, ?int $processor = null): self
{
global /** @var db $db */
$db;
// Sanitize the input
$customer_number = $db->escape_string($customer_number);
$name = $db->escape_string($name);
$notes = $db->escape_string($notes);
$processor = $db->escape_string($processor);
// Require the customer number to be of a valid customer
self::requireValidCustomer($customer_number);
// Add the object
$tmp_id = self::add_object([
'customer_number' => (int)$customer_number,
'name' => $name,
'notes' => $notes,
'processor' => $processor
]);
self::select((int)$tmp_id);
self::requireSelected();
self::objectChanged();
return $this;
}
/**
* Require the E-conomic customer number to be a valid customer
* @throws Exception If the customer number is not a valid customer
*/
private static function requireValidCustomer(string $customer_number): void
{
$customers = new users_o();
$customers->select($customer_number);
$customers->requireSelected();
}
public function objectChanged(): void
{
//TODO: Add cache invalidation
}
/**
* List all collected order invoices for a customer
* @param int $customer_number The E-conomic customer number
* @return array The list of collected order invoices
* @throws Exception If the request was not successful
*/
public function getCustomerInvoiceCollections(int $customer_number): array
{
$collections = self::getFieldsWhere(
[
'customer_number' => $customer_number,
'deleted_at' => null
],
['id', 'name', 'notes', 'processor', 'external_id', 'created_at', 'updated_at', 'closed_at']
);
// Parse the results
$result = [];
foreach ( $collections as $collection ) {
$this->id = $collection['id'];
self::getObjectProperties();
self::requireSelected();
$result[] = self::asArray();
}
return $result;
}
public function getObjectProperties(): void
{
$this->customer_number = new object_property($this->table, $this->id, 'customer_number', 'int', false);
$this->name = new object_property($this->table, $this->id, 'name', 'string', false);
$this->notes = new object_property($this->table, $this->id, 'notes', 'string', false);
$this->processor = new object_property($this->table, $this->id, 'processor', 'int', false);
$this->external_id = new object_property($this->table, $this->id, 'external_id', 'string', false);
$this->created_at = new object_property($this->table, $this->id, 'created_at', 'string', false);
$this->updated_at = new object_property($this->table, $this->id, 'updated_at', 'string', false);
$this->closed_at = new object_property($this->table, $this->id, 'closed_at', 'string', false);
}
public function asArray(): array
{
return [
'id' => (int)$this->id,
'customer_number' => (int)$this->customer_number->value(),
'name' => (string)$this->name->value(),
'notes' => (string)$this->notes->value(),
'processor' => (int)$this->processor->value(),
'external_id' => (string)$this->external_id->value(),
'created_at' => (string)$this->created_at->value(),
'updated_at' => (string)$this->updated_at->value(),
'closed_at' => (string)$this->closed_at->value(),
];
}
}
@@ -0,0 +1,145 @@
<?php
namespace routes;
use classes\authentication;
use classes\response;
use classes\router;
use objects\collected_order_invoices_o;
use objects\logs_o;
use objects\users_o;
use traits\route_t;
class orderInvoicesRoute
{
use route_t;
public function run(): void
{
global /** @var response $response */
/** @var router $router */
$router, $response;
/** Collected order invoices > GET */
$this->get('/collected-invoices', function () {
global $response;
self::requirePermission('list_collected_invoices');
$user = (new authentication())->get_user();
if ($user) {
(new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'LIST_COLLECTED_INVOICES', 'User accessed the list of collected order invoices');
$collected_order_invoices = new collected_order_invoices_o();
// Check if the request contains an ID
if (self::isParametersSet(['id'])) {
self::requireType((int)self::getParameter('id'), self::type_int());
$collected_order_invoices->select((int)self::getParameter('id'));
$collected_order_invoices->requireSelected();
$response->success($collected_order_invoices->asArray());
}
// Return the list of collected order invoices
$response->success($collected_order_invoices->listObjectsWithPaginationIfSet(
function ($collected_order_invoice) {
return [
'id' => (int)$collected_order_invoice['id'],
'name' => (string)$collected_order_invoice['name'],
'notes' => (string)$collected_order_invoice['notes'],
'customer_number' => (int)$collected_order_invoice['customer_number'],
'processor' => $collected_order_invoice['processor'] ? (int)$collected_order_invoice['processor'] : null,
'external_id' => (string)$collected_order_invoice['external_id'],
'closed_at' => $collected_order_invoice['closed_at'] ? (string)$collected_order_invoice['closed_at'] : null,
'updated_at' => (string)$collected_order_invoice['updated_at'],
'created_at' => (string)$collected_order_invoice['created_at']
];
}
));
} else {
(new logs_o())->add('orderInvoices', 'global', 0, 0, 'LIST_COLLECTED_INVOICES', 'User tried to access the list of collected order invoices without a valid session');
$response->error('Invalid session', 400);
}
},
[
'list_collected_invoices' => 'List ALL collected order invoices. This is a superuser-only route.'
]
);
/** Collected order invoices > POST */
$this->post('/collected-invoices', function () {
global $response;
self::requirePermission('add_collected_invoice');
$user = (new authentication())->get_user();
if ($user) {
(new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'ADD_COLLECTED_INVOICE', 'User added a collected order invoice');
// Require the customer number, and validate its type and length
self::requireParameters(['customer_number']);
self::requireType((int)self::getParameter('customer_number'), 'int');
self::requireMinLength('customer_number', 1);
self::requireMaxLength('customer_number', 10);
// Require the customer number to be above 0
self::requireMinValue((int)self::getParameter('customer_number'), 1);
// Validate the customer number against the database
$customer = (new users_o())->select((int)self::getParameter('customer_number'));
$customer->requireSelected();
// Define the variables
$name = null;
$notes = null;
$processor = null;
// Check if the name is set
if (self::isParametersSet(['name'])) {
self::requireType((string)self::getParameter('name'), 'string');
self::requireMinLength('name', 1);
self::requireMaxLength('name', 255);
$name = (string)self::getParameter('name');
}
// Check if the notes are set
if (self::isParametersSet(['notes'])) {
self::requireType((string)self::getParameter('notes'), 'string');
$notes = (string)self::getParameter('notes');
}
// Check if the processor is set
if (self::isParametersSet(['processor'])) {
self::requireType((int)self::getParameter('processor'), 'int');
$processor = (int)self::getParameter('processor');
}
// Add the collected order invoice
$collected_order_invoices = new collected_order_invoices_o();
$collected_order_invoices->add(
$customer->id,
$name,
$notes,
$processor
);
$response->success($collected_order_invoices->asArray());
} else {
(new logs_o())->add('orderInvoices', 'global', 0, 0, 'ADD_COLLECTED_INVOICE', 'User tried to add a collected order invoice without a valid session');
$response->error('Invalid session', 400);
}
},
[
'add_collected_invoice' => 'Add a collected order invoice. This is a superuser-only route.'
]
);
/** Modules > MotorAPI > Lookup > GET */
$this->get('/modules/motorapi/lookup', function () {
global $response;
self::requirePermission('modules_motorapi_lookup');
$user = (new authentication())->get_user();
if ($user) {
self::requireParameters(['license_plate']);
self::requireType('license_plate', 'string');
self::requireMinLength('license_plate', 1);
self::requireMaxLength('license_plate', 10);
(new logs_o())->add('modules_motorapi', 'global', 1, $user->id, 'MODULES_MOTORAPI', 'Successfully looked up license plate information');
$result = (new motorapi())->getLicensePlateInformation($this->fromRequest('license_plate'), false);
$response->success((object)$result);
} else {
(new logs_o())->add('modules_motorapi', 'global', 1, 0, 'MODULES_MOTORAPI', 'No user found, or invalid session');
$response->error('Invalid session', 400);
}
},
[
'modules_motorapi_lookup' => 'Lookup license plate information'
]
);
}
}
@@ -737,6 +737,7 @@ trait db_object_t
* Select an object by id
* @param int $id The id of the object in the database
* @returns $this
* @throws Exception If the object does not exist in the database, it throws an exception
*/
public function select(int $id): self
{
+13
View File
@@ -39,11 +39,24 @@ trait route_t
return true;
}
public function requireMinValue(int $value, int $min): void
{
global $response;
if ($value < $min) {
$response->error('Parameter must be at least ' . $min, 400);
}
}
public function type_int(): string
{
return 'integer';
}
public function type_string(): string
{
return 'string';
}
public function requireParameters(array $parameters): void
{
global $response;