mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-06-03 12:14:37 -04:00
Task imports + tests
This commit is contained in:
parent
83844a0c27
commit
57a2a836f1
@ -163,7 +163,7 @@ class BaseImport
|
|||||||
private function groupTasks($csvData, $key)
|
private function groupTasks($csvData, $key)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (! $key) {
|
if (! $key || count(array_column($csvData, $key)) == 0) {
|
||||||
return $csvData;
|
return $csvData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -448,10 +448,9 @@ class BaseImport
|
|||||||
$task_transformer = $this->transformer;
|
$task_transformer = $this->transformer;
|
||||||
|
|
||||||
$task_repository = new TaskRepository();
|
$task_repository = new TaskRepository();
|
||||||
// $task_repository->import_mode = true;
|
|
||||||
|
|
||||||
$tasks = $this->groupTasks($tasks, $task_number_key);
|
$tasks = $this->groupTasks($tasks, $task_number_key);
|
||||||
|
|
||||||
foreach ($tasks as $raw_task) {
|
foreach ($tasks as $raw_task) {
|
||||||
$task_data = [];
|
$task_data = [];
|
||||||
try {
|
try {
|
||||||
@ -496,7 +495,7 @@ class BaseImport
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
nlog($count);
|
||||||
return $count;
|
return $count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ class Csv extends BaseImport implements ImportInterface
|
|||||||
'quote',
|
'quote',
|
||||||
'bank_transaction',
|
'bank_transaction',
|
||||||
'recurring_invoice',
|
'recurring_invoice',
|
||||||
'tasks',
|
'task',
|
||||||
])
|
])
|
||||||
) {
|
) {
|
||||||
$this->{$entity}();
|
$this->{$entity}();
|
||||||
@ -362,7 +362,7 @@ class Csv extends BaseImport implements ImportInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (empty($data)) {
|
if (empty($data)) {
|
||||||
$this->entity_count['invoices'] = 0;
|
$this->entity_count['tasks'] = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -378,6 +378,8 @@ class Csv extends BaseImport implements ImportInterface
|
|||||||
$task_count = $this->ingestTasks($data, 'task.number');
|
$task_count = $this->ingestTasks($data, 'task.number');
|
||||||
|
|
||||||
$this->entity_count['tasks'] = $task_count;
|
$this->entity_count['tasks'] = $task_count;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function transform(array $data)
|
public function transform(array $data)
|
||||||
|
@ -676,6 +676,9 @@ class BaseTransformer
|
|||||||
*/
|
*/
|
||||||
public function getProjectId($name, $clientId = null)
|
public function getProjectId($name, $clientId = null)
|
||||||
{
|
{
|
||||||
|
if(strlen($name) == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
$project = Project::query()->where('company_id', $this->company->id)
|
$project = Project::query()->where('company_id', $this->company->id)
|
||||||
->where('is_deleted', false)
|
->where('is_deleted', false)
|
||||||
->whereRaw("LOWER(REPLACE(`name`, ' ' ,'')) = ?", [
|
->whereRaw("LOWER(REPLACE(`name`, ' ' ,'')) = ?", [
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
namespace App\Import\Transformer\Csv;
|
namespace App\Import\Transformer\Csv;
|
||||||
|
|
||||||
|
use App\Models\TaskStatus;
|
||||||
use App\Import\Transformer\BaseTransformer;
|
use App\Import\Transformer\BaseTransformer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -35,12 +36,14 @@ class TaskTransformer extends BaseTransformer
|
|||||||
$this->getString($task_data, 'client.email')
|
$this->getString($task_data, 'client.email')
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$projectId = $task_data['project.name'] ?? '';
|
||||||
|
|
||||||
$transformed = [
|
$transformed = [
|
||||||
'company_id' => $this->company->id,
|
'company_id' => $this->company->id,
|
||||||
'number' => $this->getString($task_data, 'task.number'),
|
'number' => $this->getString($task_data, 'task.number'),
|
||||||
'user_id' => $this->getString($task_data, 'task.user_id'),
|
'user_id' => $this->getString($task_data, 'task.user_id'),
|
||||||
'client_id' => $clientId,
|
'client_id' => $clientId,
|
||||||
'project_id' => $this->getProjectId($task_data['project.name'], $clientId),
|
'project_id' => $this->getProjectId($projectId, $clientId),
|
||||||
'description' => $this->getString($task_data, 'task.description'),
|
'description' => $this->getString($task_data, 'task.description'),
|
||||||
'status' => $this->getTaskStatusId($task_data),
|
'status' => $this->getTaskStatusId($task_data),
|
||||||
'custom_value1' => $this->getString($task_data, 'task.custom_value1'),
|
'custom_value1' => $this->getString($task_data, 'task.custom_value1'),
|
||||||
@ -49,6 +52,11 @@ class TaskTransformer extends BaseTransformer
|
|||||||
'custom_value4' => $this->getString($task_data, 'task.custom_value4'),
|
'custom_value4' => $this->getString($task_data, 'task.custom_value4'),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if(count($task_items_data) == count($task_items_data, COUNT_RECURSIVE)) {
|
||||||
|
$transformed['time_log'] = json_encode([$this->parseLog($task_items_data)]);
|
||||||
|
return $transformed;
|
||||||
|
}
|
||||||
|
|
||||||
$time_log = collect($task_items_data)
|
$time_log = collect($task_items_data)
|
||||||
->map(function ($item) {
|
->map(function ($item) {
|
||||||
|
|
||||||
@ -56,32 +64,36 @@ class TaskTransformer extends BaseTransformer
|
|||||||
|
|
||||||
})->toJson();
|
})->toJson();
|
||||||
|
|
||||||
nlog($time_log);
|
|
||||||
|
|
||||||
$transformed['time_log'] = $time_log;
|
$transformed['time_log'] = $time_log;
|
||||||
|
|
||||||
return $transformed;
|
return $transformed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function parseLog($item): array
|
private function parseLog($item)
|
||||||
{
|
{
|
||||||
$start_date = false;
|
$start_date = false;
|
||||||
$end_date = false;
|
$end_date = false;
|
||||||
|
|
||||||
$notes = $item['task.notes'] ?? '';
|
$notes = $item['task.notes'] ?? '';
|
||||||
$is_billable = $item['task.is_billable'] ?? false;
|
|
||||||
|
if(isset($item['task.is_billable']) && is_string($item['task.is_billable']) && in_array($item['task.is_billable'], ['yes', 'true', '1']))
|
||||||
|
$is_billable = true;
|
||||||
|
elseif(isset($item['task.is_billable']) && is_bool($item['task.is_billable']))
|
||||||
|
$is_billable = $item['task.is_billable'];
|
||||||
|
else
|
||||||
|
$is_billable = false;
|
||||||
|
|
||||||
if(isset($item['start_date']) &&
|
if(isset($item['task.start_date']) &&
|
||||||
isset($item['end_date'])) {
|
isset($item['task.end_date'])) {
|
||||||
$start_date = $this->resolveStartDate($item);
|
$start_date = $this->resolveStartDate($item);
|
||||||
$end_date = $this->resolveEndDate($item);
|
$end_date = $this->resolveEndDate($item);
|
||||||
} elseif(isset($item['duration'])) {
|
} elseif(isset($item['task.duration'])) {
|
||||||
$duration = strtotime($item['duration']) - strtotime('TODAY');
|
$duration = strtotime($item['task.duration']) - strtotime('TODAY');
|
||||||
$start_date = $this->stubbed_timestamp;
|
$start_date = $this->stubbed_timestamp;
|
||||||
$end_date = $this->stubbed_timestamp + $duration;
|
$end_date = $this->stubbed_timestamp + $duration;
|
||||||
$this->stubbed_timestamp++;
|
$this->stubbed_timestamp;
|
||||||
} else {
|
} else {
|
||||||
return [];
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
return [$start_date, $end_date, $notes, $is_billable];
|
return [$start_date, $end_date, $notes, $is_billable];
|
||||||
@ -90,13 +102,17 @@ class TaskTransformer extends BaseTransformer
|
|||||||
private function resolveStartDate($item)
|
private function resolveStartDate($item)
|
||||||
{
|
{
|
||||||
|
|
||||||
$stub_start_date = $item['start_date'] . ' ' . isset($item['start_time']) ?? '';
|
$stub_start_date = $item['task.start_date'];
|
||||||
|
$stub_start_date .= isset($item['task.start_time']) ? " ".$item['task.start_time'] : '';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
$stub_start_date = \Carbon\Carbon::parse($stub_start_date);
|
$stub_start_date = \Carbon\Carbon::parse($stub_start_date);
|
||||||
$this->stubbed_timestamp = $stub_start_date->timestamp;
|
$this->stubbed_timestamp = $stub_start_date->timestamp;
|
||||||
|
|
||||||
return $stub_start_date->timestamp;
|
return $stub_start_date->timestamp;
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
|
nlog($e->getMessage());
|
||||||
return $this->stubbed_timestamp;
|
return $this->stubbed_timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,22 +121,50 @@ class TaskTransformer extends BaseTransformer
|
|||||||
private function resolveEndDate($item)
|
private function resolveEndDate($item)
|
||||||
{
|
{
|
||||||
|
|
||||||
$stub_start_date = $item['end_date'] . ' ' . isset($item['end_time']) ?? '';
|
$stub_end_date = $item['task.end_date'];
|
||||||
|
$stub_end_date .= isset($item['task.end_time']) ? " ".$item['task.end_time'] : '';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$stub_start_date = \Carbon\Carbon::parse($stub_start_date);
|
|
||||||
|
|
||||||
if($stub_start_date->timestamp == $this->stubbed_timestamp) {
|
$stub_end_date = \Carbon\Carbon::parse($stub_end_date);
|
||||||
$this->stubbed_timestamp++;
|
|
||||||
|
if($stub_end_date->timestamp == $this->stubbed_timestamp) {
|
||||||
|
$this->stubbed_timestamp;
|
||||||
return $this->stubbed_timestamp;
|
return $this->stubbed_timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->stubbed_timestamp = $stub_start_date->timestamp++;
|
$this->stubbed_timestamp = $stub_end_date->timestamp;
|
||||||
return $stub_start_date->timestamp;
|
return $stub_end_date->timestamp;
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
return $this->stubbed_timestamp++;
|
nlog($e->getMessage());
|
||||||
|
|
||||||
|
return $this->stubbed_timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getTaskStatusId($item): ?int
|
||||||
|
{
|
||||||
|
if(isset($item['task.status']))
|
||||||
|
{
|
||||||
|
$name = strtolower(trim($item['task.status']));
|
||||||
|
|
||||||
|
$ts = TaskStatus::query()->where('company_id', $this->company->id)
|
||||||
|
->where('is_deleted', false)
|
||||||
|
->whereRaw("LOWER(REPLACE(`name`, ' ' ,'')) = ?", [
|
||||||
|
strtolower(str_replace(' ', '', $name)),
|
||||||
|
])
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if($ts)
|
||||||
|
return $ts->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TaskStatus::where('company_id', $this->company->id)
|
||||||
|
->where('is_deleted', false)
|
||||||
|
->orderBy('status_order', 'asc')
|
||||||
|
->first()->id ?? null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
168
tests/Feature/Import/CSV/TaskImportTest.php
Normal file
168
tests/Feature/Import/CSV/TaskImportTest.php
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Tests\Feature\Import\CSV;
|
||||||
|
|
||||||
|
use Tests\TestCase;
|
||||||
|
use App\Models\Task;
|
||||||
|
use App\Models\Client;
|
||||||
|
use App\Models\Vendor;
|
||||||
|
use App\Models\Invoice;
|
||||||
|
use App\Utils\TruthSource;
|
||||||
|
use Tests\MockAccountData;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
use App\Import\Providers\Csv;
|
||||||
|
use App\Utils\Traits\MakesHash;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
use App\Import\Transformer\BaseTransformer;
|
||||||
|
use Illuminate\Routing\Middleware\ThrottleRequests;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @covers App\Import\Providers\Csv
|
||||||
|
*/
|
||||||
|
class TaskImportTest extends TestCase
|
||||||
|
{
|
||||||
|
use MakesHash;
|
||||||
|
use MockAccountData;
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->withoutMiddleware(ThrottleRequests::class);
|
||||||
|
|
||||||
|
config(['database.default' => config('ninja.db.default')]);
|
||||||
|
|
||||||
|
$this->makeTestData();
|
||||||
|
|
||||||
|
$this->withoutExceptionHandling();
|
||||||
|
|
||||||
|
auth()->login($this->user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testTaskImportWithGroupedTaskNumbers()
|
||||||
|
{
|
||||||
|
Task::query()
|
||||||
|
->where('company_id', $this->company->id)
|
||||||
|
->forceDelete();
|
||||||
|
|
||||||
|
$this->assertEquals(0, Task::withTrashed()->where('company_id', $this->company->id)->count());
|
||||||
|
|
||||||
|
/*Need to import clients first*/
|
||||||
|
$csv = file_get_contents(
|
||||||
|
base_path().'/tests/Feature/Import/tasks2.csv'
|
||||||
|
);
|
||||||
|
$hash = Str::random(32);
|
||||||
|
$column_map = [
|
||||||
|
0 => 'task.user_id',
|
||||||
|
3 => 'project.name',
|
||||||
|
2 => 'client.name',
|
||||||
|
4 => 'task.number',
|
||||||
|
5 => 'task.description',
|
||||||
|
6 => 'task.is_billable',
|
||||||
|
7 => 'task.start_date',
|
||||||
|
9 => 'task.end_date',
|
||||||
|
8 => 'task.start_time',
|
||||||
|
10 => 'task.end_time',
|
||||||
|
11 => 'task.duration',
|
||||||
|
];
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'hash' => $hash,
|
||||||
|
'column_map' => ['task' => ['mapping' => $column_map]],
|
||||||
|
'skip_header' => true,
|
||||||
|
'import_type' => 'csv',
|
||||||
|
];
|
||||||
|
|
||||||
|
Cache::put($hash.'-task', base64_encode($csv), 360);
|
||||||
|
|
||||||
|
$csv_importer = new Csv($data, $this->company);
|
||||||
|
|
||||||
|
$this->assertInstanceOf(Csv::class, $csv_importer);
|
||||||
|
|
||||||
|
$csv_importer->import('task');
|
||||||
|
|
||||||
|
$base_transformer = new BaseTransformer($this->company);
|
||||||
|
|
||||||
|
$task = Task::where('company_id', $this->company->id)->where('number', 'x1234')->first();
|
||||||
|
$this->assertNotNull($task);
|
||||||
|
$this->assertEquals(1998, $task->calcDuration());
|
||||||
|
|
||||||
|
$time_log = json_decode($task->time_log);
|
||||||
|
|
||||||
|
foreach($time_log as $log) {
|
||||||
|
$this->assertFalse($log[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$task = Task::where('company_id', $this->company->id)->where('number', 'x1233')->first();
|
||||||
|
$this->assertNotNull($task);
|
||||||
|
$this->assertEquals(9833, $task->calcDuration());
|
||||||
|
|
||||||
|
$time_log = json_decode($task->time_log);
|
||||||
|
|
||||||
|
foreach($time_log as $log)
|
||||||
|
{
|
||||||
|
$this->assertFalse($log[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public function testTaskImport()
|
||||||
|
{
|
||||||
|
Task::query()
|
||||||
|
->where('company_id', $this->company->id)
|
||||||
|
->forceDelete();
|
||||||
|
|
||||||
|
$this->assertEquals(0, Task::withTrashed()->where('company_id', $this->company->id)->count());
|
||||||
|
|
||||||
|
/*Need to import clients first*/
|
||||||
|
$csv = file_get_contents(
|
||||||
|
base_path().'/tests/Feature/Import/tasks.csv'
|
||||||
|
);
|
||||||
|
$hash = Str::random(32);
|
||||||
|
$column_map = [
|
||||||
|
0 => 'task.user_id',
|
||||||
|
3 => 'project.name',
|
||||||
|
2 => 'client.name',
|
||||||
|
5 => 'task.description',
|
||||||
|
6 => 'task.is_billable',
|
||||||
|
7 => 'task.start_date',
|
||||||
|
9 => 'task.end_date',
|
||||||
|
8 => 'task.start_time',
|
||||||
|
10 => 'task.end_time',
|
||||||
|
11 => 'task.duration',
|
||||||
|
];
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'hash' => $hash,
|
||||||
|
'column_map' => ['task' => ['mapping' => $column_map]],
|
||||||
|
'skip_header' => true,
|
||||||
|
'import_type' => 'csv',
|
||||||
|
];
|
||||||
|
|
||||||
|
Cache::put($hash.'-task', base64_encode($csv), 360);
|
||||||
|
|
||||||
|
$csv_importer = new Csv($data, $this->company);
|
||||||
|
|
||||||
|
$this->assertInstanceOf(Csv::class, $csv_importer);
|
||||||
|
|
||||||
|
$csv_importer->import('task');
|
||||||
|
|
||||||
|
$base_transformer = new BaseTransformer($this->company);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
48
tests/Feature/Import/tasks.csv
Normal file
48
tests/Feature/Import/tasks.csv
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
User,Email,Client,Project,Task,Description,Billable,Start date,Start time,End date,End time,Duration,Tags,Amount ()
|
||||||
|
Jimmy,user@example.com,,Fixup My Code,,Short and sweet,No,2023-10-23,10:01:07,2023-10-23,12:15:02,02:13:55,,
|
||||||
|
Jimmy,user@example.com,,Fixup My Code,,,No,2023-10-23,13:07:17,2023-10-23,14:11:17,01:04:00,,
|
||||||
|
Jimmy,user@example.com,,,,Side Hustle,No,2023-10-23,14:11:19,2023-10-23,17:08:38,02:57:19,,
|
||||||
|
Bob,bob@example.com,,Fixup My Code,,,No,2023-10-23,14:49:00,2023-10-23,18:03:43,03:14:43,,
|
||||||
|
Jimmy,user@example.com,,Fixup My Code,,,No,2023-10-23,17:31:40,2023-10-23,18:18:56,00:47:16,,
|
||||||
|
Bob,bob@example.com,,,,,No,2023-10-24,10:00:00,2023-10-24,17:05:00,07:05:00,,
|
||||||
|
Jimmy,user@example.com,,Fixup My Code,,,No,2023-10-24,10:01:00,2023-10-24,10:35:55,00:34:55,,
|
||||||
|
Jimmy,user@example.com,,Gov Proj,,euro handball training,No,2023-10-24,10:35:55,2023-10-24,10:39:49,00:03:54,,
|
||||||
|
Jimmy,user@example.com,,Gov Proj,,Fix all the servers,No,2023-10-24,10:39:50,2023-10-24,11:05:25,00:25:35,,
|
||||||
|
Jimmy,user@example.com,,Gov Proj,,euro handball training,No,2023-10-24,11:05:27,2023-10-24,11:10:56,00:05:29,,
|
||||||
|
Jimmy,user@example.com,,Gov Proj,,clean the house,No,2023-10-24,11:11:08,2023-10-24,11:17:11,00:06:03,,
|
||||||
|
Jimmy,user@example.com,,Fixup My Code,,,No,2023-10-24,11:17:13,2023-10-24,11:21:36,00:04:23,,
|
||||||
|
Jimmy,user@example.com,,Gov Proj,,euro handball training,No,2023-10-24,11:21:42,2023-10-24,11:22:58,00:01:16,,
|
||||||
|
Jimmy,user@example.com,,Fixup My Code,,,No,2023-10-24,11:22:59,2023-10-24,11:32:55,00:09:56,,
|
||||||
|
Jimmy,user@example.com,,Gov Proj,,wax the floor,No,2023-10-24,11:32:55,2023-10-24,12:19:17,00:46:22,,
|
||||||
|
Jimmy,user@example.com,,Fixup My Code,,,No,2023-10-24,12:19:19,2023-10-24,12:40:57,00:21:38,,
|
||||||
|
Jimmy,user@example.com,,Fixup My Code,,,No,2023-10-24,13:18:54,2023-10-24,17:05:55,03:47:01,,
|
||||||
|
Jimmy,user@example.com,,Gov Proj,,Sand the car,No,2023-10-24,17:05:59,2023-10-24,17:08:27,00:02:28,,
|
||||||
|
Jimmy,user@example.com,,Fixup My Code,,,No,2023-10-24,17:08:29,2023-10-24,18:00:33,00:52:04,,
|
||||||
|
Bob,bob@example.com,,Fixup My Code,,,No,2023-10-25,09:58:45,2023-10-25,10:32:09,00:33:24,,
|
||||||
|
Jimmy,user@example.com,,Fixup My Code,,,No,2023-10-25,10:09:06,2023-10-25,13:01:49,02:52:43,,
|
||||||
|
Bob,bob@example.com,,Gov Proj,,Attack the windows,No,2023-10-25,10:32:10,2023-10-25,15:54:19,05:22:09,,
|
||||||
|
Jimmy,user@example.com,,Fixup My Code,,,No,2023-10-25,13:52:30,2023-10-25,15:30:48,01:38:18,,
|
||||||
|
Jimmy,user@example.com,,Gov Proj,,assist old lady to cross the street,No,2023-10-25,15:30:48,2023-10-25,15:49:10,00:18:22,,
|
||||||
|
Jimmy,user@example.com,,Fixup My Code,,,No,2023-10-25,15:49:11,2023-10-25,18:09:43,02:20:32,,
|
||||||
|
Bob,bob@example.com,,Fixup My Code,,,No,2023-10-25,16:08:29,2023-10-25,18:06:12,01:57:43,,
|
||||||
|
Jlecrenay,jlecrenay@solyme.com,,Gestion interne,,admin work,No,2023-10-26,09:24:00,2023-10-26,12:22:00,02:58:00,,
|
||||||
|
Bob,bob@example.com,,,,admin work,No,2023-10-26,09:25:49,2023-10-26,11:58:34,02:32:45,,
|
||||||
|
Jimmy,user@example.com,,,,,No,2023-10-26,09:26:22,2023-10-26,19:04:06,09:37:44,,
|
||||||
|
Bob,bob@example.com,,Fixup My Code,,administration,No,2023-10-26,13:25:23,2023-10-26,17:08:00,03:42:37,,
|
||||||
|
Jlecrenay,jlecrenay@solyme.com,,Holiday Project,,training,No,2023-10-26,13:37:31,2023-10-26,18:14:00,04:36:29,,
|
||||||
|
Jlecrenay,jlecrenay@solyme.com,,,,reading,No,2023-10-27,08:37:17,2023-10-27,09:24:45,00:47:28,,
|
||||||
|
Jlecrenay,jlecrenay@solyme.com,,LOCATION,,travel,No,2023-10-27,09:25:29,2023-10-27,09:41:46,00:16:17,,
|
||||||
|
Jlecrenay,jlecrenay@solyme.com,,,,travel,No,2023-10-27,09:42:04,2023-10-27,10:46:35,01:04:31,,
|
||||||
|
Jimmy,user@example.com,,Fixup My Code,,travel,No,2023-10-27,09:55:02,2023-10-27,10:25:52,00:30:50,,
|
||||||
|
Bob,bob@example.com,,Fixup My Code,,travel,No,2023-10-27,10:10:00,2023-10-27,10:44:00,00:34:00,,
|
||||||
|
Jimmy,user@example.com,,Gov Proj,,travel,No,2023-10-27,10:25:53,2023-10-27,10:41:22,00:15:29,,
|
||||||
|
Jimmy,user@example.com,,Gov Proj,,travel,No,2023-10-27,10:41:23,2023-10-27,10:59:56,00:18:33,,
|
||||||
|
Bob,bob@example.com,,Fixup My Code,,,No,2023-10-27,10:44:00,2023-10-27,10:59:00,00:15:00,,
|
||||||
|
Jlecrenay,jlecrenay@solyme.com,,Holiday Project,,travel,No,2023-10-27,10:46:38,2023-10-27,12:20:13,01:33:35,,
|
||||||
|
Jimmy,user@example.com,,Gov Proj,,travel,No,2023-10-27,11:01:42,2023-10-27,11:06:01,00:04:19,,
|
||||||
|
Jimmy,user@example.com,,Fixup My Code,,,No,2023-10-27,11:09:38,2023-10-27,12:20:07,01:10:29,,
|
||||||
|
Jimmy,user@example.com,,Fixup My Code,,,No,2023-10-27,13:02:18,2023-10-27,13:57:17,00:54:59,,
|
||||||
|
Jlecrenay,jlecrenay@solyme.com,,Covert Ops,,Holiday,No,2023-10-27,13:20:27,2023-10-27,18:10:58,04:50:31,,
|
||||||
|
Jimmy,user@example.com,,Gov Proj,,fix the wifi,No,2023-10-27,13:57:17,2023-10-27,14:39:11,00:41:54,,
|
||||||
|
Bob,bob@example.com,,Gov Proj,,fix the spark plugs,No,2023-10-27,14:29:25,2023-10-27,16:31:24,02:01:59,,
|
||||||
|
Jimmy,user@example.com,,BLOOM,,travel,No,2023-10-27,14:39:12,2023-10-27,15:12:30,00:33:18,,
|
|
48
tests/Feature/Import/tasks2.csv
Normal file
48
tests/Feature/Import/tasks2.csv
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
User,Email,Client,Project,Task,Description,Billable,Start date,Start time,End date,End time,Duration,Tags,Amount ()
|
||||||
|
Bob,user@example.com,,Fixup My Code,x111,Short and sweet,No,2023-10-23,10:01:07,2023-10-23,12:15:02,02:13:55,,
|
||||||
|
Bob,user@example.com,,Fixup My Code,x111,,No,2023-10-23,13:07:17,2023-10-23,14:11:17,01:04:00,,
|
||||||
|
Bob,user@example.com,,,,Side Hustle,No,2023-10-23,14:11:19,2023-10-23,17:08:38,02:57:19,,
|
||||||
|
James,james@example.com,,Fixup My Code,x111,,No,2023-10-23,14:49:00,2023-10-23,18:03:43,03:14:43,,
|
||||||
|
Bob,user@example.com,,Fixup My Code,x111,,No,2023-10-23,17:31:40,2023-10-23,18:18:56,00:47:16,,
|
||||||
|
James,james@example.com,,,,,No,2023-10-24,10:00:00,2023-10-24,17:05:00,07:05:00,,
|
||||||
|
Bob,user@example.com,,Fixup My Code,,,No,2023-10-24,10:01:00,2023-10-24,10:35:55,00:34:55,,
|
||||||
|
Bob,user@example.com,,Gov Proj,x112,euro handball training,No,2023-10-24,10:35:55,2023-10-24,10:39:49,00:03:54,,
|
||||||
|
Bob,user@example.com,,Gov Proj,x112,Fix all the servers,No,2023-10-24,10:39:50,2023-10-24,11:05:25,00:25:35,,
|
||||||
|
Bob,user@example.com,,Gov Proj,x112,euro handball training,No,2023-10-24,11:05:27,2023-10-24,11:10:56,00:05:29,,
|
||||||
|
Bob,user@example.com,,Gov Proj,x112,clean the house,No,2023-10-24,11:11:08,2023-10-24,11:17:11,00:06:03,,
|
||||||
|
Bob,user@example.com,,Fixup My Code,,,No,2023-10-24,11:17:13,2023-10-24,11:21:36,00:04:23,,
|
||||||
|
Bob,user@example.com,,Gov Proj,,euro handball training,No,2023-10-24,11:21:42,2023-10-24,11:22:58,00:01:16,,
|
||||||
|
Bob,user@example.com,,Fixup My Code,,,No,2023-10-24,11:22:59,2023-10-24,11:32:55,00:09:56,,
|
||||||
|
Bob,user@example.com,,Gov Proj,,wax the floor,No,2023-10-24,11:32:55,2023-10-24,12:19:17,00:46:22,,
|
||||||
|
Bob,user@example.com,,Fixup My Code,,,No,2023-10-24,12:19:19,2023-10-24,12:40:57,00:21:38,,
|
||||||
|
Bob,user@example.com,,Fixup My Code,,,No,2023-10-24,13:18:54,2023-10-24,17:05:55,03:47:01,,
|
||||||
|
Bob,user@example.com,,Gov Proj,,Sand the car,No,2023-10-24,17:05:59,2023-10-24,17:08:27,00:02:28,,
|
||||||
|
Bob,user@example.com,,Fixup My Code,,,No,2023-10-24,17:08:29,2023-10-24,18:00:33,00:52:04,,
|
||||||
|
James,james@example.com,,Fixup My Code,,,No,2023-10-25,09:58:45,2023-10-25,10:32:09,00:33:24,,
|
||||||
|
Bob,user@example.com,,Fixup My Code,,,No,2023-10-25,10:09:06,2023-10-25,13:01:49,02:52:43,,
|
||||||
|
James,james@example.com,,Gov Proj,,Attack the windows,No,2023-10-25,10:32:10,2023-10-25,15:54:19,05:22:09,,
|
||||||
|
Bob,user@example.com,,Fixup My Code,,,No,2023-10-25,13:52:30,2023-10-25,15:30:48,01:38:18,,
|
||||||
|
Bob,user@example.com,,Gov Proj,,assist old lady to cross the street,No,2023-10-25,15:30:48,2023-10-25,15:49:10,00:18:22,,
|
||||||
|
Bob,user@example.com,,Fixup My Code,,,No,2023-10-25,15:49:11,2023-10-25,18:09:43,02:20:32,,
|
||||||
|
James,james@example.com,,Fixup My Code,,,No,2023-10-25,16:08:29,2023-10-25,18:06:12,01:57:43,,
|
||||||
|
Jlecrenay,jlecrenay@solyme.com,,Gestion interne,,admin work,No,2023-10-26,09:24:00,2023-10-26,12:22:00,02:58:00,,
|
||||||
|
James,james@example.com,,,,admin work,No,2023-10-26,09:25:49,2023-10-26,11:58:34,02:32:45,,
|
||||||
|
Bob,user@example.com,,,,,No,2023-10-26,09:26:22,2023-10-26,19:04:06,09:37:44,,
|
||||||
|
James,james@example.com,,Fixup My Code,,administration,No,2023-10-26,13:25:23,2023-10-26,17:08:00,03:42:37,,
|
||||||
|
Jlecrenay,jlecrenay@solyme.com,,Holiday Project,,training,No,2023-10-26,13:37:31,2023-10-26,18:14:00,04:36:29,,
|
||||||
|
Jlecrenay,jlecrenay@solyme.com,,,,reading,No,2023-10-27,08:37:17,2023-10-27,09:24:45,00:47:28,,
|
||||||
|
Jlecrenay,jlecrenay@solyme.com,,LOCATION,,travel,No,2023-10-27,09:25:29,2023-10-27,09:41:46,00:16:17,,
|
||||||
|
Jlecrenay,jlecrenay@solyme.com,,,,travel,No,2023-10-27,09:42:04,2023-10-27,10:46:35,01:04:31,,
|
||||||
|
Bob,user@example.com,,Fixup My Code,,travel,No,2023-10-27,09:55:02,2023-10-27,10:25:52,00:30:50,,
|
||||||
|
James,james@example.com,,Fixup My Code,,travel,No,2023-10-27,10:10:00,2023-10-27,10:44:00,00:34:00,,
|
||||||
|
Bob,user@example.com,,Gov Proj,,travel,No,2023-10-27,10:25:53,2023-10-27,10:41:22,00:15:29,,
|
||||||
|
Bob,user@example.com,,Gov Proj,,travel,No,2023-10-27,10:41:23,2023-10-27,10:59:56,00:18:33,,
|
||||||
|
James,james@example.com,,Fixup My Code,,,No,2023-10-27,10:44:00,2023-10-27,10:59:00,00:15:00,,
|
||||||
|
Jlecrenay,jlecrenay@solyme.com,,Holiday Project,,travel,No,2023-10-27,10:46:38,2023-10-27,12:20:13,01:33:35,,
|
||||||
|
Bob,user@example.com,,Gov Proj,,travel,No,2023-10-27,11:01:42,2023-10-27,11:06:01,00:04:19,,
|
||||||
|
Bob,user@example.com,,Fixup My Code,,,No,2023-10-27,11:09:38,2023-10-27,12:20:07,01:10:29,,
|
||||||
|
Bob,user@example.com,,Fixup My Code,,,No,2023-10-27,13:02:18,2023-10-27,13:57:17,00:54:59,,
|
||||||
|
Jlecrenay,jlecrenay@solyme.com,,Covert Ops,,Holiday,No,2023-10-27,13:20:27,2023-10-27,18:10:58,04:50:31,,
|
||||||
|
Bob,user@example.com,,Gov Proj,x1233,fix the wifi,No,2023-10-27,13:57:17,2023-10-27,14:39:11,00:41:54,,
|
||||||
|
James,james@example.com,,Gov Proj,x1233,fix the spark plugs,No,2023-10-27,14:29:25,2023-10-27,16:31:24,02:01:59,,
|
||||||
|
Bob,user@example.com,,BLOOM,x1234,travel,No,2023-10-27,14:39:12,2023-10-27,15:12:30,00:33:18,,
|
|
Loading…
x
Reference in New Issue
Block a user