Files
api/services/nginx/app/routes/orderInvoicesRoute.php
T
Jepp9350 5f65c5ea65 Add new routes and enhance invoice handling in backend
Introduced new superuser-only routes for handling collected invoices, including viewing invoices per order/month, invoice totals, and transactions. Enhanced validation for invoice closure with processors and added support for database views in multiple classes and objects. These updates improve backend functionality and data granularity while maintaining strict permission control.
2025-04-01 11:53:54 +02:00

503 lines
28 KiB
PHP

<?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());
}
// Define the users
$users = new users_o();
// Define the collected order invoices
$tmp_collected_order_invoices = new collected_order_invoices_o();
// Return the list of collected order invoices
$response->success($collected_order_invoices->listObjectsWithPaginationIfSet(
function ($collected_order_invoice) use ($tmp_collected_order_invoices, $users) {
// Select the orders for each collected order invoice
$tmp_collected_order_invoices->select((int)$collected_order_invoice['id']);
return $this->getOrderInvoiceDetails($collected_order_invoice, $users, $tmp_collected_order_invoices);
},
));
} 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 > Ready to invoice > GET */
$this->get('/collected-invoices/ready-to-invoice', 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_READY_TO_INVOICE', 'User accessed the list of collected order invoices ready to invoice');
$collected_order_invoices = new collected_order_invoices_o();
// Define the users
$users = new users_o();
// Define the collected order invoices
$tmp_collected_order_invoices = new collected_order_invoices_o();
// Return the list of collected order invoices
$response->success($collected_order_invoices->listObjectsWithPaginationIfSet(
function ($collected_order_invoice) use ($tmp_collected_order_invoices, $users) {
// Select the orders for each collected order invoice
$tmp_collected_order_invoices->select((int)$collected_order_invoice['id']);
return $this->getOrderInvoiceDetails($collected_order_invoice, $users, $tmp_collected_order_invoices);
},
$collected_order_invoices->forceRestrictFilters(
[
// This makes sure that the user can only see orders from the departments they explicitly have access to
'customer_number' => $collected_order_invoices->listCustomersWithIndividualOrderInvoicing(),
]
)
));
} else {
(new logs_o())->add('orderInvoices', 'global', 0, 0, 'LIST_COLLECTED_INVOICES_READY_TO_INVOICE', 'User tried to access the list of collected order invoices ready to invoice 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.'
]
);
/** Collected order invoices > E-Conomic > POST */
$this->post('/collected-invoices/economic', function () {
global $response;
self::requirePermission('add_collected_invoice_economic');
$user = (new authentication())->get_user();
if ($user) {
(new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'ADD_COLLECTED_INVOICE_ECONOMIC', 'User added a collected order invoice to E-Conomic');
// Require the ID, and validate its type and length
self::requireParameters(['id']);
self::requireType((int)self::getParameter('id'), self::type_int());
self::requireMinLength('id', 1);
self::requireMaxLength('id', 10);
// Require the ID to be above 0
self::requireMinValue((int)self::getParameter('id'), 1);
// Validate the ID against the database
$collected_order_invoices = (new collected_order_invoices_o())->select((int)self::getParameter('id'));
$collected_order_invoices->requireSelected();
// Check if the collected order invoice has an external ID
if ($collected_order_invoices->external_id->value() === null) {
// Add the collected order invoice to E-Conomic
$collected_order_invoices->addToEconomic();
$response->success($collected_order_invoices->asArray());
}
// Check if the invoice has been booked
if ($collected_order_invoices->booked_invoice_id->value() !== null) {
$response->error('Invoice has already been booked', 400);
}
// Check if the invoice draft exists in E-Conomic
if ($collected_order_invoices->isDraftExisting()) {
$response->error('Invoice draft already exists in E-Conomic', 400);
}
// Create the invoice in E-Conomic
$collected_order_invoices->addToEconomic(true);
// Return the collected order invoice
$response->success($collected_order_invoices->asArray());
} else {
(new logs_o())->add('orderInvoices', 'global', 0, 0, 'ADD_COLLECTED_INVOICE_ECONOMIC', 'User tried to add a collected order invoice to E-Conomic without a valid session');
$response->error('Invalid session', 400);
}
},
[
'add_collected_invoice_economic' => 'Add a collected order invoice to E-Conomic. This is a superuser-only route.'
]
);
/** Collected order invoices > Open > GET Customers */
$this->get('/collected-invoices/customers', 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_CUSTOMERS', 'User accessed the list of collected order invoices customers');
// Define the users
$users_o = new users_o();
$tmp_customer_numbers = $users_o->getCustomerNumbersWithAttributes([
'invoiceAllOrdersIndividually'
]);
// Filter out the customers that do not have any open invoices
$customer_numbers = [];
//print_r($tmp_customer_numbers);
foreach ( $tmp_customer_numbers as $customer_number ) {
// This is the customers open invoices, this might contain invoices that's empty, or only contains deleted orders.
$tmp_customer_open_invoice_ids = [];
// This is the net amount of the total transactions for the customer
$tmp_total_net_amount = 0;
// This is the number of invoices, that's not empty.
$tmp_customer_active_invoice_ids = [];
$collected_order_invoices = new collected_order_invoices_o();
$customer_open_invoices = $collected_order_invoices->listObjectsWithPaginationIfSet(
function ($collected_order_invoice) use ($tmp_total_net_amount, $users_o, $collected_order_invoices) {
// Select the orders for each collected order invoice
$collected_order_invoices->select((int)$collected_order_invoice['id']);
// Return the details
return $this->getOrderInvoiceDetails($collected_order_invoice, $users_o, $collected_order_invoices);
},
$collected_order_invoices->forceRestrictFilters([
'customer_number' => $customer_number,
'closed_at' => 'null',
])
);
//print_r($customer_open_invoices);
// Check if the customer has any open invoices
if (count($customer_open_invoices) > 0) {
$tmp_customer_orders = 0;
// Get the total net amount of the open invoices
foreach ( $customer_open_invoices as $customer_open_invoice ) {
// Check if the invoice is empty
if (count($customer_open_invoice['orders']) === 0) {
continue;
}
// Add the invoice collected order invoice ID to the list (if it's not already in the list)
if (!in_array($customer_open_invoice['id'], $tmp_customer_open_invoice_ids)) {
$tmp_customer_active_invoice_ids[] = $customer_open_invoice['id'];
}
// Update the total net amount, and the number of orders
$tmp_customer_open_invoice_ids[] = $customer_open_invoice['id'];
$tmp_total_net_amount += $customer_open_invoice['total_net_amount'];
$tmp_customer_orders += count($customer_open_invoice['orders']);
}
// If the open invoices are not empty, add the customer to the list
if (empty($tmp_customer_orders)) {
continue;
}
$tmp_user = (new users_o())->getUserByCustomerNumber($customer_number);
$customer_numbers[] = array(
'customer_number' => $customer_number,
'customer_name' => $users_o->getCustomerName($customer_number),
'user_id' => $tmp_user->id,
'open_invoices' => $customer_open_invoices,
'active_invoices' => $tmp_customer_active_invoice_ids,
'orders' => $tmp_customer_orders,
'total_net_amount' => $tmp_total_net_amount,
);
}
}
// Return the list of customers
$response->success($customer_numbers);
} else {
(new logs_o())->add('orderInvoices', 'global', 0, 0, 'LIST_COLLECTED_INVOICES_CUSTOMERS', 'User tried to access the list of collected order invoices customers without a valid session');
$response->error('Invalid session', 400);
}
},
[
'list_collected_invoices_customers' => 'List ALL collected order invoices customers. This is a superuser-only route.'
]
);
$this->get('/collected-invoices/customers/invoicePerOrder', 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_CUSTOMERS_INVOICE_PER_ORDER', 'User accessed the list of collected order invoices customers with invoice per order');
// Define the users
$users_o = new users_o();
$users_o->setView('customers_invoice_count_per_order');
$result = $users_o
->setSearchableFields([
'customer_number',
'display_name',
'active_invoices',
'closed_invoices',
])
->listObjectsWithPaginationIfSet(
function ($collected_order_invoice) use ($users_o) {
return [
'customer_number' => (int)$collected_order_invoice['customer_number'],
'display_name' => (string)$users_o->getCustomerName((int)$collected_order_invoice['customer_number']),
'active_invoices' => (int)$collected_order_invoice['active_invoices'],
'closed_invoices' => (int)$collected_order_invoice['closed_invoices'],
];
},
);
// Return the list of customers
$response->success($result);
} else {
(new logs_o())->add('orderInvoices', 'global', 0, 0, 'LIST_COLLECTED_INVOICES_CUSTOMERS_INVOICE_PER_ORDER', 'User tried to access the list of collected order invoices customers with invoice per order without a valid session');
$response->error('Invalid session', 400);
}
},
[
'list_collected_invoices_customers_invoice_per_order' => 'List ALL collected order invoices customers with invoice per order. This is a superuser-only route.'
]
);
$this->get('/collected-invoices/customers/invoicePerMonth', 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_CUSTOMERS_INVOICE_PER_MONTH', 'User accessed the list of collected order invoices customers with invoice per month');
// Define the users
$users_o = new users_o();
$users_o->setView('customers_invoice_count_per_month');
$result = $users_o
->setSearchableFields([
'customer_number',
'customer_name',
'active_invoices',
'closed_invoices',
])
->listObjectsWithPaginationIfSet(
function ($collected_order_invoice) use ($users_o) {
return [
'customer_number' => (int)$collected_order_invoice['customer_number'],
'display_name' => (string)$users_o->getCustomerName((int)$collected_order_invoice['customer_number']),
'active_invoices' => (int)$collected_order_invoice['active_invoices'],
'closed_invoices' => (int)$collected_order_invoice['closed_invoices'],
];
},
);
// Return the list of customers
$response->success($result);
} else {
(new logs_o())->add('orderInvoices', 'global', 0, 0, 'LIST_COLLECTED_INVOICES_CUSTOMERS_INVOICE_PER_MONTH', 'User tried to access the list of collected order invoices customers with invoice per month without a valid session');
$response->error('Invalid session', 400);
}
},
[
'list_collected_invoices_customers_invoice_per_month' => 'List ALL collected order invoices customers with invoice per month. This is a superuser-only route.'
]
);
$this->post('/collected-invoices/customers/invoiceTotals', function () {
// This is a superuser-only route
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_CUSTOMERS_INVOICE_TOTALS', 'User accessed the list of collected order invoices customers with invoice totals');
// Require the customer_numbers parameter
self::requireParameters(['customer_numbers']);
// Print the customer_numbers parameter
$customer_numbers = self::getParameter('customer_numbers');
// validate the customer_numbers parameter
if (!is_array($customer_numbers)) {
$response->error('customer_numbers must be an array', 400);
}
// Validate the customer_numbers parameter
foreach ( $customer_numbers as $customer_number ) {
self::requireType((int)$customer_number, self::type_int());
if (!is_numeric($customer_number)) {
$response->error('customer_numbers must be an array of integers', 400);
}
if (!$customer_number || $customer_number < 1) {
$response->error('customer_numbers must be an array of integers greater than 0', 400);
}
}
// Now we can safely use the customer_numbers parameter
// Define the result array
$result = [];
// Loop through the customer_numbers array, and get the invoice totals for each customer
foreach ( $customer_numbers as $customer_number ) {
// Define the invoices array
$tmp_invoices = [
'closed_invoices' => [],
'open_invoices' => [],
];
// Define the total net amount
$tmp_total_net_amount = [
'closed_invoices' => 0,
'open_invoices' => 0,
];
// Define the collected order invoices
$collected_order_invoices = new collected_order_invoices_o();
// Get the collected order invoices for the customer
$collected_order_invoices->setView('invoices_with_completed_orders');
$tmp_invoice_collections = $collected_order_invoices->listObjectsWithPaginationIfSet(
function ($collected_order_invoice) use ($tmp_invoices, $customer_number, $collected_order_invoices) {
// Select the orders for each collected order invoice
$collected_order_invoices->select((int)$collected_order_invoice['id']);
// Get the details for the collected order invoice
return $this->getOrderInvoiceDetails($collected_order_invoice, new users_o(), $collected_order_invoices);
},
$collected_order_invoices->forceRestrictFilters([
'customer_number' => $customer_number,
])
);
// Loop through the collected order invoices, and get the total net amount
foreach ( $tmp_invoice_collections as $tmp_invoice_collection ) {
// Update the total net amount
if ($tmp_invoice_collection['closed_at'] !== null) {
$tmp_total_net_amount['closed_invoices'] += $tmp_invoice_collection['total_net_amount'];
// Add the closed invoice to the closed invoices array
$tmp_invoices['closed_invoices'][] = $tmp_invoice_collection;
} else {
$tmp_total_net_amount['open_invoices'] += $tmp_invoice_collection['total_net_amount'];
// Add the open invoice to the open invoices array
$tmp_invoices['open_invoices'][] = $tmp_invoice_collection;
}
}
$tmp_user = (new users_o())->getUserByCustomerNumber($customer_number);
// Add the customer to the result array
$result[$customer_number] = [
'customer_number' => (int)$customer_number,
'customer_name' => (string)$tmp_user->display_name->value(),
'user_id' => (int)$tmp_user->id,
'invoices' => $tmp_invoices,
'total_net_amount' => $tmp_total_net_amount,
];
}
// Return the list of customers
$response->success($result);
} else {
(new logs_o())->add('orderInvoices', 'global', 0, 0, 'LIST_COLLECTED_INVOICES_CUSTOMERS_INVOICE_TOTALS', 'User tried to access the list of collected order invoices customers with invoice totals without a valid session');
$response->error('Invalid session', 400);
}
});
$this->get('/collected-invoices/transactions', 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_TRANSACTIONS', 'User accessed the list of collected order invoices transactions');
// Get the collected order invoices
$collected_order_invoices = new collected_order_invoices_o();
// Define the transactions
$transactions = $orders_o->listObjectsWithPaginationIfSet(
function ($order) use ($orders_o) {
// Select the orders for each collected order invoice
$orders_o->select((int)$order['id']);
return [
'id' => (int)$order['id'],
'customer_number' => (int)$order['customer_number'],
'external_id' => (string)$order['external_id'],
'created_at' => (string)$order['created_at'],
'updated_at' => (string)$order['updated_at'],
];
},
);
// Return the list of transactions
$response->success($transactions);
} else {
(new logs_o())->add('orderInvoices', 'global', 0, 0, 'LIST_COLLECTED_INVOICES_TRANSACTIONS', 'User tried to access the list of collected order invoices transactions without a valid session');
$response->error('Invalid session', 400);
}
},
[
'list_collected_invoices_transactions' => 'List ALL collected order invoices transactions. This is a superuser-only route.'
]
);
}
/**
* @param $collected_order_invoice
* @param users_o $users
* @param collected_order_invoices_o $tmp_collected_order_invoices
* @return array
* @throws \Exception
*/
function getOrderInvoiceDetails($collected_order_invoice, users_o $users, collected_order_invoices_o $tmp_collected_order_invoices): array
{
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'],
'customer_name' => (string)$users->getCustomerName((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'],
'orders' => $tmp_collected_order_invoices->getOrders(),
'total_net_amount' => (float)$tmp_collected_order_invoices->getTotalAmount(),
];
}
}