Files
api/services/nginx/app/statistics/economic_s.php
T
Jepp9350 7186b27b74 Improve invoice fetching and add vehicle plate lookup API
Refactored the invoice retrieval to handle pagination for both drafts and booked invoices, ensuring all results are fetched when exceeding the limit. Added a new route for vehicle plate lookup, allowing retrieval of order history for a specified vehicle plate. Implemented the corresponding database query method in `orders_o`.
2025-02-05 16:18:52 +01:00

419 lines
17 KiB
PHP

<?php
namespace statistics;
use classes\economic;
use traits\statistic_t;
class economic_s
{
use statistic_t;
/**
* Get the totals for the invoices
* WARNING: This is function does NOT support time filtering
* @return $this
*/
public function get_totals(): economic_s
{
// Get the economic class
$economic = new economic();
// Get the totals
$data = $economic->invoices->totals->get();
// Add the data
$this->add_data_set('Drafts', [
'netAmountInBaseCurrency' => $data->drafts->netAmountInBaseCurrency,
'invoiceCount' => $data->drafts->invoiceCount,
]);
$this->add_data_set('Booked', [
'netAmountInBaseCurrency' => $data->booked->netAmountInBaseCurrency,
'invoiceCount' => $data->booked->invoiceCount,
]);
$this->add_data_set('Unpaid', [
'netAmountInBaseCurrency' => $data->booked->unpaid->netAmountInBaseCurrency,
'invoiceCount' => $data->booked->unpaid->invoiceCount,
]);
$this->add_data_set('Not Overdue', [
'netAmountInBaseCurrency' => $data->booked->unpaid->notOverdue->netAmountInBaseCurrency,
'invoiceCount' => $data->booked->unpaid->notOverdue->invoiceCount,
]);
$this->add_data_set('Overdue', [
'netAmountInBaseCurrency' => $data->booked->unpaid->overdue->netAmountInBaseCurrency,
'invoiceCount' => $data->booked->unpaid->overdue->invoiceCount,
]);
$this->add_data_set('Paid', [
'netAmountInBaseCurrency' => $data->booked->paid->netAmountInBaseCurrency,
'invoiceCount' => $data->booked->paid->invoiceCount,
]);
return $this;
}
/**
* Get department sent invoice total amount and count
* @return $this
*/
public function get_department_sent_invoice_totals(): economic_s
{
// Get the economic class
$economic = new economic();
// Get the totals
$invoices = $economic->invoices->booked->get([
'(date$gte:' . $this->start . '$and:date$lte:' . $this->end . ')' => '', // To allow for time filtering, we need to add the time frame to the query
])->collection;
// Get the departments
$departments = $economic->departments->departments->get(
[],
[
'skipPages' => 0,
'pageSize' => 1000, // Since the limit is 1000, we need to set the page size to 1000.
]
)->collection;
/**
* To get the department name from the department number, we need to create an array with the department number as the key and the department name as the value.
* This results in an array like this:
* departmentNumber => name
* [
* 10 => ['name' => 'Department 1', 'departmentNumber' => 10, 'products' => ['product 1' => 10, 'product 2' => 20], 'totalNetAmount' => 0],
* 20 => ['name' => 'Department 2', 'departmentNumber' => 20, 'products' => ['product 1' => 10, 'product 2' => 20], 'totalNetAmount' => 0],
* ]
*/
$departments_temp = array_column($departments, 'name', 'departmentNumber');
// Add an unknown (0) department, in case the departmentDistributionNumber is not set
$departments_temp[0] = 'Unknown';
$departments = [];
foreach ( $departments_temp as $departmentNumber => $name ) {
$departments[$departmentNumber] = [
'name' => $name,
'departmentNumber' => $departmentNumber,
'products' => [],
'totalNetAmount' => 0,
'invoiceCount' => 0,
];
}
// Get the bookedInvoiceNumbers
$booked_invoice_numbers = [];
foreach ( $invoices as $invoice ) {
$booked_invoice_numbers[] = $invoice->bookedInvoiceNumber;
}
// Get the invoice lines
$invoice_lines = $economic->invoices->booked->get_invoice_lines($booked_invoice_numbers);
// Clear the invoice lines that has quantity 0, since they don't have any value to the statistics
foreach ( $invoice_lines as $invoice_id => $lines ) {
foreach ( $lines as $key => $line ) {
if ($line->quantity == 0) {
unset($invoice_lines[$invoice_id][$key]);
}
}
}
// Add the net amount, invoice count and products array to the departments
foreach ( $invoice_lines as $invoice_id => $lines ) {
foreach ( $lines as $line ) {
// Check if the departmentDistributionNumber is set and the quantity is greater than 0
$tmp_department = 0;
if (isset($line->departmentalDistribution->departmentalDistributionNumber)) {
// Set the department to unknown
$tmp_department = $line->departmentalDistribution->departmentalDistributionNumber;
}
if ($line->quantity == 0) {
// Skip the line if the quantity is 0
continue;
}
// Add the net amount to the department
$departments[$tmp_department]['totalNetAmount'] += $line->totalNetAmount;
// Add the product to the department
if (!isset($departments[$tmp_department]['products'][$line->product->productNumber])) {
$departments[$tmp_department]['products'][$line->product->productNumber] = 0;
}
$departments[$tmp_department]['products'][$line->product->productNumber] += $line->quantity;
// Add the invoice count to the department
$departments[$tmp_department]['invoiceCount']++;
}
}
// Add the data sets
foreach ( $departments as $department ) {
$this->add_data_set($department['name'], [
'Faktureret (DKK)' => $department['totalNetAmount'],
]);
$this->set_raw_data($department['departmentNumber'], [
'invoiceCount' => $department['invoiceCount'],
'products' => $department['products'],
'totalNetAmount' => $department['totalNetAmount'],
'name' => $department['name'],
]);
}
return $this;
}
/**
* Get department draft invoice total amount and count
* @return $this
*/
public function get_department_draft_invoice_totals(): economic_s
{
// Get the economic class
$economic = new economic();
// Get the totals
$invoices = $economic->invoices->drafts->get([
'(date$gte:' . $this->start . '$and:date$lte:' . $this->end . ')' => '', // To allow for time filtering, we need to add the time frame to the query
])->collection;
// Get the departments
$departments = $economic->departments->departments->get(
[],
[
'skipPages' => 0,
'pageSize' => 1000, // Since the limit is 1000, we need to set the page size to 1000.
]
)->collection;
/**
* To get the department name from the department number, we need to create an array with the department number as the key and the department name as the value.
* This results in an array like this:
* departmentNumber => name
* [
* 10 => ['name' => 'Department 1', 'departmentNumber' => 10, 'products' => ['product 1' => 10, 'product 2' => 20], 'totalNetAmount' => 0],
* 20 => ['name' => 'Department 2', 'departmentNumber' => 20, 'products' => ['product 1' => 10, 'product 2' => 20], 'totalNetAmount' => 0],
* ]
*/
$departments_temp = array_column($departments, 'name', 'departmentNumber');
// Add an unknown (0) department, in case the departmentDistributionNumber is not set
$departments_temp[0] = 'Unknown';
$departments = [];
foreach ( $departments_temp as $departmentNumber => $name ) {
$departments[$departmentNumber] = [
'name' => $name,
'departmentNumber' => $departmentNumber,
'products' => [],
'totalNetAmount' => 0,
'invoiceCount' => 0,
];
}
// Get the draftInvoiceNumber for the draft invoices
$draft_invoice_number = [];
foreach ( $invoices as $invoice ) {
$draft_invoice_number[] = $invoice->draftInvoiceNumber;
}
// Get the invoice lines
$invoice_lines = $economic->invoices->drafts->get_invoice_lines($draft_invoice_number);
// Clear the invoice lines that has quantity 0, since they don't have any value to the statistics
foreach ( $invoice_lines as $invoice_id => $lines ) {
foreach ( $lines as $key => $line ) {
// If the quantity key does not exist, we can just set the quantity to 0
if (!isset($line->quantity)) {
$line->quantity = 0;
}
// If the quantity is 0, we can unset the line, since it does not have any value to the statistics
if ($line->quantity == 0) {
unset($invoice_lines[$invoice_id][$key]);
}
}
}
// Add the net amount, invoice count and products array to the departments
foreach ( $invoice_lines as $invoice_id => $lines ) {
foreach ( $lines as $line ) {
// Check if the departmentDistributionNumber is set and the quantity is greater than 0
$tmp_department = 0;
if (isset($line->departmentalDistribution->departmentalDistributionNumber)) {
// Set the department to unknown
$tmp_department = $line->departmentalDistribution->departmentalDistributionNumber;
}
if ($line->quantity == 0) {
// Skip the line if the quantity is 0
continue;
}
// Add the net amount to the department
$departments[$tmp_department]['totalNetAmount'] += $line->totalNetAmount;
// Add the product to the department
if (!isset($departments[$tmp_department]['products'][$line->product->productNumber])) {
$departments[$tmp_department]['products'][$line->product->productNumber] = 0;
}
$departments[$tmp_department]['products'][$line->product->productNumber] += $line->quantity;
// Add the invoice count to the department
$departments[$tmp_department]['invoiceCount']++;
}
}
// Add the data sets
foreach ( $departments as $department ) {
$this->add_data_set($department['name'], [
'Faktureret (DKK)' => $department['totalNetAmount'],
]);
$this->set_raw_data($department['departmentNumber'], [
'invoiceCount' => $department['invoiceCount'],
'products' => $department['products'],
'totalNetAmount' => $department['totalNetAmount'],
'name' => $department['name'],
]);
}
return $this;
}
/**
* Get the total invoiced amount today
* @return array ['drafts' => object, 'booked' => object]
*/
public function get_totals_today(): array
{
return self::get_totals_in_time_frame(date('Y-m-d'), date('Y-m-d'));
}
/**
* Get the total invoiced amount today
* @return array ['drafts' => object, 'booked' => object]
*/
protected function get_totals_in_time_frame(string $start = null, string $end = null): array
{
// Set the date range to the current day, if no start and end date is set
$start = $start ?? date('Y-m-d');
$end = $end ?? date('Y-m-d');
// Get the economic class
$economic = new economic();
$repeat['drafts'] = [
'invoiceCount' => 0,
'repeat' => true,
'pageCount' => 0,
];
$drafts = [];
while ($repeat['drafts']['repeat']) {
$repeat['drafts']['repeat'] = false;
// Merge the draft collection, since the limit is 1000, we need to get all the drafts
$drafts_tmp = $economic->invoices->drafts->get([
'(date$gte:' . $start . '$and:date$lte:' . $end . ')' => '', // To allow for time filtering, we need to add the time frame to the query
],
[
'skipPages' => $repeat['drafts']['pageCount'],
'pageSize' => 1000, // Since the limit is 1000, we need to set the page size to 1000.
]
)->collection;
$drafts = array_merge($drafts, $drafts_tmp);
// If the count of the drafts is equal to the limit, we need to repeat the process
if (count($drafts_tmp) == 1000) {
$repeat['drafts']['repeat'] = true;
$repeat['drafts']['pageCount']++;
}
}
$repeat['booked'] = [
'invoiceCount' => 0,
'repeat' => true,
'pageCount' => 0,
];
$booked = [];
while ($repeat['booked']['repeat']) {
$repeat['booked']['repeat'] = false;
// Merge the booked collection, since the limit is 1000, we need to get all the booked
$booked_tmp = $economic->invoices->booked->get([
'(date$gte:' . $start . '$and:date$lte:' . $end . ')' => '', // To allow for time filtering, we need to add the time frame to the query
],
[
'skipPages' => $repeat['booked']['invoiceCount'],
'pageSize' => 1000, // Since the limit is 1000, we need to set the page size to 1000.
]
)->collection;
$booked = array_merge($booked, $booked_tmp);
// If the count of the booked is equal to the limit, we need to repeat the process
if (count($booked_tmp) == 1000) {
$repeat['booked']['repeat'] = true;
$repeat['booked']['pageCount']++;
}
}
$drafts_total = 0;
$booked_total = 0;
foreach ( $drafts as $draft_obj ) {
$drafts_total += $draft_obj->netAmountInBaseCurrency;
}
foreach ( $booked as $booked_obj ) {
$booked_total += $booked_obj->netAmountInBaseCurrency;
}
return [
'drafts' => [
'netAmountInBaseCurrency' => $drafts_total,
'invoiceCount' => count($drafts),
],
'booked' => [
'netAmountInBaseCurrency' => $booked_total,
'invoiceCount' => count($booked),
],
'total' => $drafts_total + $booked_total,
'start' => $start,
'end' => $end,
];
}
/**
* Get the total invoiced amount this week
* @return array ['drafts' => object, 'booked' => object]
*/
public function get_totals_this_week(): array
{
return self::get_totals_in_time_frame(date('Y-m-d', strtotime('monday this week')), date('Y-m-d'));
}
/**
* Get the total invoiced amount this month 1st to last day of the month
* @return array ['drafts' => object, 'booked' => object]
*/
public function get_totals_this_month(): array
{
return self::get_totals_in_time_frame(date('Y-m-01'), date('Y-m-t'));
}
/**
* Get the total invoiced amount last month 1st to last day of the month
* @return array ['drafts' => object, 'booked' => object]
*/
public function get_totals_last_month(): array
{
return self::get_totals_in_time_frame(date('Y-m-01', strtotime('last month')), date('Y-m-t', strtotime('last month')));
}
/**
* Get the total invoiced amount last year
* @return array ['drafts' => object, 'booked' => object]
*/
public function get_totals_last_year(): array
{
return self::get_totals_in_time_frame(date('Y-01-01', strtotime('last year')), date('Y-12-31', strtotime('last year')));
}
/**
* Get the total invoiced amount yesterday
* @return array ['drafts' => object, 'booked' => object]
*/
public function get_totals_yesterday(): array
{
return self::get_totals_in_time_frame(date('Y-m-d', strtotime('yesterday')), date('Y-m-d', strtotime('yesterday')));
}
/**
* Get the total invoiced amount this year
* @return array ['drafts' => object, 'booked' => object]
*/
public function get_totals_this_year(): array
{
return self::get_totals_in_time_frame(date('Y-01-01'), date('Y-12-31'));
}
public function get_totals_departments()
{
// Get the
}
}