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`.
419 lines
17 KiB
PHP
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
|
|
}
|
|
|
|
} |