291 lines
12 KiB
PHP
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;
|
|
}
|
|
} |