mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-08 12:12:48 +01:00
Additional tests for report generation
This commit is contained in:
parent
9fc9a0fd78
commit
a2b0a13c1f
@ -20,6 +20,7 @@ use App\Models\Payment;
|
||||
use League\Fractal\Manager;
|
||||
use Illuminate\Support\Carbon;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\Transformers\TaskTransformer;
|
||||
use App\Transformers\PaymentTransformer;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use League\Fractal\Serializer\ArraySerializer;
|
||||
@ -348,8 +349,6 @@ class BaseExport
|
||||
'custom_value4' => 'task.custom_value4',
|
||||
'status' => 'task.status_id',
|
||||
'project' => 'task.project_id',
|
||||
'invoice' => 'task.invoice_id',
|
||||
'client' => 'task.client_id',
|
||||
];
|
||||
|
||||
protected function filterByClients($query)
|
||||
@ -385,6 +384,7 @@ class BaseExport
|
||||
'quote' => $value = $this->resolveQuoteKey($parts[1], $entity, $transformer),
|
||||
'purchase_order' => $value = $this->resolvePurchaseOrderKey($parts[1], $entity, $transformer),
|
||||
'payment' => $value = $this->resolvePaymentKey($parts[1], $entity, $transformer),
|
||||
'task' => $value = $this->resolveTaskKey($parts[1], $entity, $transformer),
|
||||
default => $value = ''
|
||||
};
|
||||
|
||||
@ -450,6 +450,22 @@ class BaseExport
|
||||
|
||||
}
|
||||
|
||||
private function resolveTaskKey($column, $entity, $transformer)
|
||||
{
|
||||
nlog("searching for {$column}");
|
||||
|
||||
$transformed_entity = $transformer->transform($entity);
|
||||
|
||||
if(array_key_exists($column, $transformed_entity)) {
|
||||
return $transformed_entity[$column];
|
||||
}
|
||||
|
||||
return '';
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private function resolveVendorKey($column, $entity, $transformer)
|
||||
{
|
||||
|
||||
@ -587,7 +603,23 @@ class BaseExport
|
||||
|
||||
}
|
||||
|
||||
$transformed_invoice = $transformer->transform($entity);
|
||||
if($transformer instanceof TaskTransformer) {
|
||||
$transformed_invoice = $transformer->includeInvoice($entity);
|
||||
|
||||
if(!$transformed_invoice)
|
||||
return '';
|
||||
|
||||
$manager = new Manager();
|
||||
$manager->setSerializer(new ArraySerializer());
|
||||
$transformed_invoice = $manager->createData($transformed_invoice)->toArray();
|
||||
|
||||
}
|
||||
|
||||
if(array_key_exists($column, $transformed_invoice)) {
|
||||
return $transformed_invoice[$column];
|
||||
} elseif (array_key_exists(str_replace("invoice.", "", $column), $transformed_invoice)) {
|
||||
return $transformed_invoice[$column];
|
||||
}
|
||||
|
||||
if($column == 'status')
|
||||
return $entity->stringStatus($entity->status_id);
|
||||
@ -886,6 +918,8 @@ class BaseExport
|
||||
}
|
||||
}
|
||||
|
||||
// nlog($header);
|
||||
|
||||
return $header;
|
||||
}
|
||||
}
|
||||
|
@ -46,9 +46,7 @@ class TaskExport extends BaseExport
|
||||
'custom_value4' => 'custom_value4',
|
||||
'status' => 'status_id',
|
||||
'project' => 'project_id',
|
||||
'invoice' => 'invoice_id',
|
||||
'client' => 'client_id',
|
||||
];
|
||||
];
|
||||
|
||||
private array $decorate_keys = [
|
||||
'status',
|
||||
@ -109,38 +107,39 @@ class TaskExport extends BaseExport
|
||||
$entity = [];
|
||||
$transformed_entity = $this->entity_transformer->transform($task);
|
||||
|
||||
foreach (array_values($this->input['report_keys']) as $key) {
|
||||
$keyval = array_search($key, $this->entity_keys);
|
||||
|
||||
if(!$keyval) {
|
||||
$keyval = array_search(str_replace("task.", "", $key), $this->entity_keys) ?? $key;
|
||||
}
|
||||
|
||||
if(!$keyval) {
|
||||
$keyval = $key;
|
||||
}
|
||||
|
||||
if (array_key_exists($key, $transformed_entity)) {
|
||||
$entity[$keyval] = $transformed_entity[$key];
|
||||
} elseif (array_key_exists($keyval, $transformed_entity)) {
|
||||
$entity[$keyval] = $transformed_entity[$keyval];
|
||||
}
|
||||
else {
|
||||
$entity[$keyval] = $this->resolveKey($keyval, $task, $this->entity_transformer);
|
||||
}
|
||||
}
|
||||
|
||||
$entity['start_date'] = '';
|
||||
$entity['end_date'] = '';
|
||||
$entity['duration'] = '';
|
||||
|
||||
|
||||
if (is_null($task->time_log) || (is_array(json_decode($task->time_log, 1)) && count(json_decode($task->time_log, 1)) == 0)) {
|
||||
foreach (array_values($this->input['report_keys']) as $key) {
|
||||
$keyval = array_search($key, $this->entity_keys);
|
||||
|
||||
if (array_key_exists($key, $transformed_entity)) {
|
||||
$entity[$keyval] = $transformed_entity[$key];
|
||||
} else {
|
||||
$entity[$keyval] = '';
|
||||
}
|
||||
}
|
||||
|
||||
$entity['start_date'] = '';
|
||||
$entity['end_date'] = '';
|
||||
$entity['duration'] = '';
|
||||
|
||||
$entity = $this->decorateAdvancedFields($task, $entity);
|
||||
|
||||
ksort($entity);
|
||||
$this->csv->insertOne($entity);
|
||||
} elseif (is_array(json_decode($task->time_log, 1)) && count(json_decode($task->time_log, 1)) > 0) {
|
||||
foreach (array_values($this->input['report_keys']) as $key) {
|
||||
$keyval = array_search($key, $this->entity_keys);
|
||||
|
||||
if (array_key_exists($key, $transformed_entity)) {
|
||||
$entity[$keyval] = $transformed_entity[$key];
|
||||
} else {
|
||||
$entity[$keyval] = '';
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
$this->iterateLogs($task, $entity);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private function iterateLogs(Task $task, array $entity)
|
||||
@ -163,39 +162,26 @@ class TaskExport extends BaseExport
|
||||
}
|
||||
|
||||
foreach ($logs as $key => $item) {
|
||||
if (in_array('start_date', $this->input['report_keys'])) {
|
||||
if (in_array('task.start_date', $this->input['report_keys']) || in_array('start_date', $this->input['report_keys'])) {
|
||||
$entity['start_date'] = Carbon::createFromTimeStamp($item[0])->setTimezone($timezone_name)->format($date_format_default);
|
||||
}
|
||||
|
||||
if (in_array('end_date', $this->input['report_keys']) && $item[1] > 0) {
|
||||
if ((in_array('task.end_date', $this->input['report_keys']) || in_array('end_date', $this->input['report_keys'])) && $item[1] > 0) {
|
||||
$entity['end_date'] = Carbon::createFromTimeStamp($item[1])->setTimezone($timezone_name)->format($date_format_default);
|
||||
}
|
||||
|
||||
if (in_array('end_date', $this->input['report_keys']) && $item[1] == 0) {
|
||||
if ((in_array('task.end_date', $this->input['report_keys']) || in_array('end_date', $this->input['report_keys'])) && $item[1] == 0) {
|
||||
$entity['end_date'] = ctrans('texts.is_running');
|
||||
}
|
||||
|
||||
if (in_array('duration', $this->input['report_keys'])) {
|
||||
if (in_array('task.duration', $this->input['report_keys']) || in_array('duration', $this->input['report_keys'])) {
|
||||
$entity['duration'] = $task->calcDuration();
|
||||
}
|
||||
|
||||
if (! array_key_exists('duration', $entity)) {
|
||||
$entity['duration'] = '';
|
||||
}
|
||||
|
||||
if (! array_key_exists('start_date', $entity)) {
|
||||
$entity['start_date'] = '';
|
||||
}
|
||||
|
||||
if (! array_key_exists('end_date', $entity)) {
|
||||
$entity['end_date'] = '';
|
||||
}
|
||||
|
||||
|
||||
$entity = $this->decorateAdvancedFields($task, $entity);
|
||||
|
||||
ksort($entity);
|
||||
|
||||
$this->csv->insertOne($entity);
|
||||
|
||||
|
||||
unset($entity['start_date']);
|
||||
unset($entity['end_date']);
|
||||
unset($entity['duration']);
|
||||
@ -212,14 +198,6 @@ class TaskExport extends BaseExport
|
||||
$entity['project'] = $task->project()->exists() ? $task->project->name : '';
|
||||
}
|
||||
|
||||
if (in_array('client_id', $this->input['report_keys'])) {
|
||||
$entity['client'] = $task->client ? $task->client->present()->name() : '';
|
||||
}
|
||||
|
||||
if (in_array('invoice_id', $this->input['report_keys'])) {
|
||||
$entity['invoice'] = $task->invoice ? $task->invoice->number : '';
|
||||
}
|
||||
|
||||
return $entity;
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ class TaskTransformer extends EntityTransformer
|
||||
'status',
|
||||
'project',
|
||||
'user',
|
||||
'invoice',
|
||||
];
|
||||
|
||||
public function includeDocuments(Task $task)
|
||||
@ -46,6 +47,17 @@ class TaskTransformer extends EntityTransformer
|
||||
return $this->includeCollection($task->documents, $transformer, Document::class);
|
||||
}
|
||||
|
||||
public function includeInvoice(Task $task): ?Item
|
||||
{
|
||||
$transformer = new InvoiceTransformer($this->serializer);
|
||||
|
||||
if (!$task->user) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->includeItem($task->invoice, $transformer, Invoice::class);
|
||||
}
|
||||
|
||||
public function includeUser(Task $task): ?Item
|
||||
{
|
||||
$transformer = new UserTransformer($this->serializer);
|
||||
|
@ -5,7 +5,7 @@ parameters:
|
||||
treatPhpDocTypesAsCertain: false
|
||||
parallel:
|
||||
jobSize: 5
|
||||
maximumNumberOfProcesses: 16
|
||||
maximumNumberOfProcesses: 1
|
||||
processTimeout: 600.0
|
||||
ignoreErrors:
|
||||
- '#Call to an undefined method .*badMethod\(\)#'
|
||||
|
@ -164,9 +164,92 @@ class ReportCsvGenerationTest extends TestCase
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function testTaskCustomColumnsCsvGeneration()
|
||||
{
|
||||
|
||||
|
||||
$invoice = \App\Models\Invoice::factory()->create([
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $this->company->id,
|
||||
'client_id' => $this->client->id,
|
||||
'date' => '2023-01-01',
|
||||
'amount' => 1000,
|
||||
'balance' => 1000,
|
||||
'number' => '123456',
|
||||
'status_id' => 2,
|
||||
'discount' => 10,
|
||||
'po_number' => '12345',
|
||||
'public_notes' => 'Public5',
|
||||
'private_notes' => 'Private5',
|
||||
'terms' => 'Terms5',
|
||||
]);
|
||||
|
||||
|
||||
$log = '[[1689547165,1689550765,"sumtin",true]]';
|
||||
|
||||
\App\Models\Task::factory()->create([
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $this->company->id,
|
||||
'client_id' => $this->client->id,
|
||||
'invoice_id' => $invoice->id,
|
||||
'description' => 'test1',
|
||||
'time_log' => $log,
|
||||
'custom_value1' => 'Custom 11',
|
||||
'custom_value2' => 'Custom 22',
|
||||
'custom_value3' => 'Custom 33',
|
||||
'custom_value4' => 'Custom 44',
|
||||
]);
|
||||
|
||||
$data = [
|
||||
'date_range' => 'all',
|
||||
'report_keys' => [
|
||||
'client.name',
|
||||
'invoice.number',
|
||||
'invoice.amount',
|
||||
'task.start_date',
|
||||
'task.end_date',
|
||||
'task.duration',
|
||||
'task.description',
|
||||
'task.custom_value1',
|
||||
'task.custom_value2',
|
||||
'task.custom_value3',
|
||||
'task.custom_value4',
|
||||
],
|
||||
'send_email' => false,
|
||||
];
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->post('/api/v1/reports/tasks', $data);
|
||||
|
||||
$csv = $response->streamedContent();
|
||||
|
||||
$this->assertEquals(3600, $this->getFirstValueByColumn($csv, 'Task Duration'));
|
||||
$this->assertEquals('test1', $this->getFirstValueByColumn($csv, 'Task Description'));
|
||||
$this->assertEquals('16/Jul/2023', $this->getFirstValueByColumn($csv, 'Task Start Date'));
|
||||
$this->assertEquals('16/Jul/2023', $this->getFirstValueByColumn($csv, 'Task End Date'));
|
||||
$this->assertEquals('Custom 11', $this->getFirstValueByColumn($csv, 'Task Custom Value 1'));
|
||||
$this->assertEquals('Custom 22', $this->getFirstValueByColumn($csv, 'Task Custom Value 2'));
|
||||
$this->assertEquals('Custom 33', $this->getFirstValueByColumn($csv, 'Task Custom Value 3'));
|
||||
$this->assertEquals('Custom 44', $this->getFirstValueByColumn($csv, 'Task Custom Value 4'));
|
||||
$this->assertEquals('bob', $this->getFirstValueByColumn($csv, 'Client Name'));
|
||||
$this->assertEquals('123456', $this->getFirstValueByColumn($csv, 'Invoice Invoice Number'));
|
||||
$this->assertEquals(1000, $this->getFirstValueByColumn($csv, 'Invoice Amount'));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public function testTasksCsvGeneration()
|
||||
{
|
||||
|
||||
\App\Models\Task::query()->cursor()->each(function ($t) {
|
||||
$t->forceDelete();
|
||||
});
|
||||
|
||||
$log = '[[1689547165,1689550765,"sumtin",true]]';
|
||||
|
||||
\App\Models\Task::factory()->create([
|
||||
@ -247,13 +330,70 @@ class ReportCsvGenerationTest extends TestCase
|
||||
|
||||
|
||||
public function testPaymentCsvGeneration()
|
||||
{
|
||||
|
||||
$invoice = \App\Models\Invoice::factory()->create([
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $this->company->id,
|
||||
'client_id' => $this->client->id,
|
||||
'date' => '2023-01-01',
|
||||
'amount' => 100,
|
||||
'balance' => 100,
|
||||
'number' => '12345',
|
||||
'status_id' => 2,
|
||||
'discount' => 10,
|
||||
'po_number' => '1234',
|
||||
'public_notes' => 'Public',
|
||||
'private_notes' => 'Private',
|
||||
'terms' => 'Terms',
|
||||
]);
|
||||
|
||||
$invoice->client->balance = 100;
|
||||
$invoice->client->paid_to_date = 0;
|
||||
$invoice->push();
|
||||
|
||||
$invoice->service()->markPaid()->save();
|
||||
|
||||
$data = [
|
||||
'date_range' => 'all',
|
||||
'report_keys' => [
|
||||
"payment.date",
|
||||
"payment.amount",
|
||||
"invoice.number",
|
||||
"invoice.amount",
|
||||
"client.name",
|
||||
"client.balance",
|
||||
"client.paid_to_date"
|
||||
],
|
||||
'send_email' => false,
|
||||
];
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->post('/api/v1/reports/payments', $data);
|
||||
|
||||
$csv = $response->streamedContent();
|
||||
|
||||
$this->assertEquals(100, $this->getFirstValueByColumn($csv, 'Payment Amount'));
|
||||
$this->assertEquals(now()->addSeconds($this->company->timezone()->utc_offset)->format('Y-m-d'), $this->getFirstValueByColumn($csv, 'Payment Date'));
|
||||
$this->assertEquals('12345', $this->getFirstValueByColumn($csv, 'Invoice Invoice Number'));
|
||||
$this->assertEquals(100, $this->getFirstValueByColumn($csv, 'Invoice Amount'));
|
||||
$this->assertEquals('bob', $this->getFirstValueByColumn($csv, 'Client Name'));
|
||||
$this->assertEquals(0, $this->getFirstValueByColumn($csv, 'Client Balance'));
|
||||
$this->assertEquals(100, $this->getFirstValueByColumn($csv, 'Client Paid to Date'));
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function testPaymentCustomFieldsCsvGeneration()
|
||||
{
|
||||
|
||||
\App\Models\Payment::factory()->create([
|
||||
'amount' => 500,
|
||||
'date' => '2020-01-01',
|
||||
'company_id' => $this->company->id,
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $this->company->id,
|
||||
'client_id' => $this->client->id,
|
||||
'transaction_reference' => '1234',
|
||||
]);
|
||||
@ -279,6 +419,7 @@ class ReportCsvGenerationTest extends TestCase
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function testClientCsvGeneration()
|
||||
{
|
||||
|
||||
@ -443,8 +584,6 @@ class ReportCsvGenerationTest extends TestCase
|
||||
|
||||
$csv = $response->streamedContent();
|
||||
|
||||
nlog($csv);
|
||||
|
||||
$this->assertEquals('bob', $this->getFirstValueByColumn($csv, 'Client Name'));
|
||||
$this->assertEquals('1234', $this->getFirstValueByColumn($csv, 'Recurring Invoice Invoice Number'));
|
||||
$this->assertEquals('Daily', $this->getFirstValueByColumn($csv, 'Recurring Invoice How Often'));
|
||||
@ -694,8 +833,6 @@ class ReportCsvGenerationTest extends TestCase
|
||||
|
||||
$csv = $response->streamedContent();
|
||||
|
||||
nlog($csv);
|
||||
|
||||
$this->assertEquals('Vendor 1', $this->getFirstValueByColumn($csv, 'Vendor Name'));
|
||||
$this->assertEquals('1234', $this->getFirstValueByColumn($csv, 'Purchase Order Number'));
|
||||
$this->assertEquals('10', $this->getFirstValueByColumn($csv, 'Quantity'));
|
||||
|
Loading…
Reference in New Issue
Block a user