Files
api/services/nginx/app/routes/InvoicingPeriodRoute.php
T

291 lines
12 KiB
PHP

<?php
namespace routes;
use classes\authentication;
use Exception;
use objects\customer_vehicles_o;
use objects\logs_o;
use objects\orders_o;
use traits\route_t;
class InvoicingPeriodRoute
{
use route_t;
public function run(): void
{
$this->get('/superuser/invoicing/period', function () {
// Require the user to be logged in
global $response;
$this->requirePermission('superuser_invoicing_period');
// Get the user object
$user = (new authentication())->get_user();
// Check if the request was successful
if ($user) {
self::requireParameters([
'dateFrom',
'dateTo',
]);
$dateFrom = $this->getParameter('dateFrom');
$dateTo = $this->getParameter('dateTo');
// Require the dateFrom and dateTo parameters to be valid dates
self::requireDateFormat($dateFrom, 'Y-m-d');
self::requireDateFormat($dateTo, 'Y-m-d');
// 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');
// Return an error
$response->error('Invalid session', 400);
}
},
[
'superuser_invoicing_period' => 'Get the invoicing period for superusers',
]
);
}
/**
* @throws Exception
*/
private static function getInvoicingPeriod(string $dateFrom, string $dateTo): array
{
return [
'dateFrom' => $dateFrom,
'dateTo' => $dateTo,
'types' => [
'vehicle_subscriptions' => self::getVehicleSubscriptions($dateFrom, $dateTo),
'fixed_pricing' => self::getFixedPricing($dateFrom, $dateTo),
'tank_cleaning' => self::getTankCleaning($dateFrom, $dateTo),
'all' => self::getCustomersWithTransactions($dateFrom, $dateTo),
],
];
}
/**
* @throws Exception
*/
private static function getVehicleSubscriptions(string $dateFrom, string $dateTo): array
{
// Get all customers with vehicle subscriptions
$customer_numbers = (new \objects\users_o())->getCustomersWithVehicleSubscriptions();
$subscriptions = [];
/** @var int $customer_number */
foreach ( $customer_numbers as $customer_number ) {
$tmp_subscription = [
'customer_number' => $customer_number,
'customer_name' => (new \objects\users_o())->getCustomerName($customer_number),
'transactions' => [],
'requires_action' => true,
];
// Check if the customer has a vehicle subscription order within the date range
$orders = (new \objects\orders_o())->getWashSubscriptionTransactions($customer_number, false, $dateFrom, $dateTo);
/** @var orders_o $order */
foreach ( $orders as $order ) {
//echo "Checking order {$order->id} for customer {$customer_number}...\n";
// Add the order to the subscription transactions
$tmp_subscription['transactions'][] = [
'id' => $order->id,
];
}
// If there are transactions, set requires_action to false
if (count($tmp_subscription['transactions']) > 0) {
// Check if there's any transaction that has not been booked yet
$requires_action = false;
foreach ( $tmp_subscription['transactions'] as $transaction ) {
$order = (new orders_o())->select((int)$transaction['id']);
if (!$order->isBooked()) {
$requires_action = true;
break;
}
}
$tmp_subscription['requires_action'] = $requires_action;
}
// Add the subscription to the list if it has transactions
$subscriptions[] = $tmp_subscription;
}
return $subscriptions;
}
/**
* @throws Exception
*/
private static function getFixedPricing(string $dateFrom, string $dateTo): array
{
// Get all customers with fixed pricing
$customer_numbers = (new \objects\users_o())->getCustomersWithFixedPricing();
$fixed_pricing = [];
/** @var int $customer_number */
foreach ( $customer_numbers as $customer_number ) {
$tmp_fixed_pricing = [
'customer_number' => $customer_number,
'customer_name' => (new \objects\users_o())->getCustomerName($customer_number),
'transactions' => [],
'requires_action' => true,
];
// Check if the customer has a fixed pricing order within the date range
$orders = (new \objects\orders_o())->getFixedPricingTransactions($customer_number, false, $dateFrom, $dateTo);
/** @var orders_o $order */
foreach ( $orders as $order ) {
// Add the order to the fixed pricing transactions
$tmp_fixed_pricing['transactions'][] = [
'id' => $order->id,
];
}
// If there are transactions, set requires_action to false
if (count($tmp_fixed_pricing['transactions']) > 0) {
// Check if there's any transaction that has not been booked yet
$requires_action = false;
foreach ( $tmp_fixed_pricing['transactions'] as $transaction ) {
$order = (new orders_o())->select((int)$transaction['id']);
if (!$order->isBooked()) {
$requires_action = true;
break;
}
}
// Set requires_action based on the transactions
$tmp_fixed_pricing['requires_action'] = $requires_action;
}
// Add the fixed pricing to the list if it has transactions
$fixed_pricing[] = $tmp_fixed_pricing;
}
return $fixed_pricing;
}
/**
* @throws Exception
*/
private static function getTankCleaning(string $dateFrom, string $dateTo): array
{
// Get all customers with tank cleaning
$customer_numbers = (new \objects\users_o())->getCustomersWithTankCleaning();
$tank_cleaning = [];
/** @var int $customer_number */
foreach ( $customer_numbers as $customer_number ) {
$tmp_tank_cleaning = [
'customer_number' => $customer_number,
'customer_name' => (new \objects\users_o())->getCustomerName($customer_number),
'transactions' => [],
'requires_action' => false,
];
// Check if the customer has a tank cleaning order within the date range
$orders = (new \objects\orders_o())->getTankCleaningTransactions($customer_number, false, $dateFrom, $dateTo);
/** @var orders_o $order */
foreach ( $orders as $order ) {
// Add the order to the tank cleaning transactions
$tmp_tank_cleaning['transactions'][] = [
'id' => $order->id,
];
}
// If there are transactions, set requires_action to false
if (count($tmp_tank_cleaning['transactions']) > 0) {
// Check if there's any transaction that has not been booked yet
$requires_action = false;
foreach ( $tmp_tank_cleaning['transactions'] as $transaction ) {
$order = (new orders_o())->select($transaction['id']);
if (!$order->isBooked()) {
$requires_action = true;
break;
}
}
$tmp_tank_cleaning['requires_action'] = $requires_action;
}
// Add the tank cleaning to the list if it has transactions
$tank_cleaning[] = $tmp_tank_cleaning;
}
return $tank_cleaning;
}
/**
* @throws Exception
*/
private static function getCustomersWithTransactions(string $dateFrom, string $dateTo): array
{
// Define the customers with orders in the specified date range
$customers = (new orders_o)->getCustomersWithOrdersInDateRange($dateFrom, $dateTo);
$customer_numbers_processed = [];
$tmp = [];
foreach ( $customers as $customer ) {
if (in_array((int)$customer->customer_number->value(), $customer_numbers_processed)) {
// Skip if the customer has already been processed
continue;
}
$customer_numbers_processed[] = (int)$customer->customer_number->value();
// Construct the customer object with transactions
$tmp[] = self::constructCustomerObject(
(int)$customer->customer_number->value(),
(new \objects\users_o())->getCustomerName((int)$customer->customer_number->value()),
(new \objects\orders_o())->getTransactionsForCustomer(
(int)$customer->customer_number->value(),
$dateFrom,
$dateTo
),
);
}
return $tmp;
}
/**
* @param int $customer_number
* @param string $customer_name
* @param orders_o[] $transactions
* @param bool $requires_action
* @return array
* @throws Exception
*/
protected static function constructCustomerObject(
int $customer_number,
string $customer_name,
array $transactions = [],
bool $requires_action = false
): array
{
return [
'customer_number' => $customer_number,
'customer_name' => $customer_name,
'transactions' => $parsed_transactions = array_map(function ($transaction) {
return [
'id' => $transaction->id,
'date' => $transaction->created_at->value(),
'amount' => $transaction->getNetAmount(),
'booked' => $transaction->isBooked(),
];
}, $transactions),
'requires_action' => self::checkRequiresAction($parsed_transactions, $requires_action),
];
}
private static function checkRequiresAction(array $parsed_transactions, bool $requires_action): bool
{
// If requires_action is already set to true, return true
if ($requires_action) {
return true;
}
// Check if any transaction is not booked
foreach ( $parsed_transactions as $transaction ) {
if (!$transaction['booked']) {
return true;
}
}
// If all transactions are booked, return false
return false;
}
}