From e248e9686877c9bc9ec9f599e31bece83efe57d8 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 9 May 2024 10:15:46 +1000 Subject: [PATCH 1/6] Refactor for start / end of quarters --- app/Export/CSV/BaseExport.php | 12 ++++++------ app/Services/Report/ProfitLoss.php | 8 ++++---- app/Services/Scheduler/EmailStatementService.php | 4 ++-- app/Utils/Traits/MakesDates.php | 4 ++-- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/app/Export/CSV/BaseExport.php b/app/Export/CSV/BaseExport.php index c43223fc8f96..31cfb9b05c04 100644 --- a/app/Export/CSV/BaseExport.php +++ b/app/Export/CSV/BaseExport.php @@ -1281,13 +1281,13 @@ class BaseExport $this->end_date = now()->startOfMonth()->subMonth()->endOfMonth()->format('Y-m-d'); return $query->whereBetween($this->date_key, [now()->startOfMonth()->subMonth(), now()->startOfMonth()->subMonth()->endOfMonth()])->orderBy($this->date_key, 'ASC'); case 'this_quarter': - $this->start_date = (new \Carbon\Carbon('-3 months'))->firstOfQuarter()->format('Y-m-d'); - $this->end_date = (new \Carbon\Carbon('-3 months'))->lastOfQuarter()->format('Y-m-d'); - return $query->whereBetween($this->date_key, [(new \Carbon\Carbon('-3 months'))->firstOfQuarter(), (new \Carbon\Carbon('-3 months'))->lastOfQuarter()])->orderBy($this->date_key, 'ASC'); + $this->start_date = (new \Carbon\Carbon('0 months'))->startOfQuarter()->format('Y-m-d'); + $this->end_date = (new \Carbon\Carbon('0 months'))->endOfQuarter()->format('Y-m-d'); + return $query->whereBetween($this->date_key, [(new \Carbon\Carbon('0 months'))->startOfQuarter(), (new \Carbon\Carbon('0 months'))->endOfQuarter()])->orderBy($this->date_key, 'ASC'); case 'last_quarter': - $this->start_date = (new \Carbon\Carbon('-6 months'))->firstOfQuarter()->format('Y-m-d'); - $this->end_date = (new \Carbon\Carbon('-6 months'))->lastOfQuarter()->format('Y-m-d'); - return $query->whereBetween($this->date_key, [(new \Carbon\Carbon('-6 months'))->firstOfQuarter(), (new \Carbon\Carbon('-6 months'))->lastOfQuarter()])->orderBy($this->date_key, 'ASC'); + $this->start_date = (new \Carbon\Carbon('-3 months'))->startOfQuarter()->format('Y-m-d'); + $this->end_date = (new \Carbon\Carbon('-3 months'))->endOfQuarter()->format('Y-m-d'); + return $query->whereBetween($this->date_key, [(new \Carbon\Carbon('-3 months'))->startOfQuarter(), (new \Carbon\Carbon('-3 months'))->endOfQuarter()])->orderBy($this->date_key, 'ASC'); case 'last365_days': $this->start_date = now()->startOfDay()->subDays(365)->format('Y-m-d'); $this->end_date = now()->startOfDay()->format('Y-m-d'); diff --git a/app/Services/Report/ProfitLoss.php b/app/Services/Report/ProfitLoss.php index 3b81e11bd5d4..812978d665eb 100644 --- a/app/Services/Report/ProfitLoss.php +++ b/app/Services/Report/ProfitLoss.php @@ -618,13 +618,13 @@ class ProfitLoss break; case 'this_quarter': - $this->start_date = (new \Carbon\Carbon('-3 months'))->firstOfQuarter(); - $this->end_date = (new \Carbon\Carbon('-3 months'))->lastOfQuarter(); + $this->start_date = (new \Carbon\Carbon('0 months'))->startOfQuarter(); + $this->end_date = (new \Carbon\Carbon('0 months'))->endOfQuarter(); break; case 'last_quarter': - $this->start_date = (new \Carbon\Carbon('-6 months'))->firstOfQuarter(); - $this->end_date = (new \Carbon\Carbon('-6 months'))->lastOfQuarter(); + $this->start_date = (new \Carbon\Carbon('-3 months'))->startOfQuarter(); + $this->end_date = (new \Carbon\Carbon('-3 months'))->endOfQuarter(); break; case 'this_year': diff --git a/app/Services/Scheduler/EmailStatementService.php b/app/Services/Scheduler/EmailStatementService.php index 1111090a8c07..84b5be63ce19 100644 --- a/app/Services/Scheduler/EmailStatementService.php +++ b/app/Services/Scheduler/EmailStatementService.php @@ -92,8 +92,8 @@ class EmailStatementService EmailStatement::LAST365 => [now()->startOfDay()->subDays(365)->format('Y-m-d'), now()->startOfDay()->format('Y-m-d')], EmailStatement::THIS_MONTH => [now()->startOfDay()->firstOfMonth()->format('Y-m-d'), now()->startOfDay()->lastOfMonth()->format('Y-m-d')], EmailStatement::LAST_MONTH => [now()->startOfDay()->subMonthNoOverflow()->firstOfMonth()->format('Y-m-d'), now()->startOfDay()->subMonthNoOverflow()->lastOfMonth()->format('Y-m-d')], - EmailStatement::THIS_QUARTER => [now()->startOfDay()->firstOfQuarter()->format('Y-m-d'), now()->startOfDay()->lastOfQuarter()->format('Y-m-d')], - EmailStatement::LAST_QUARTER => [now()->startOfDay()->subQuarterNoOverflow()->firstOfQuarter()->format('Y-m-d'), now()->startOfDay()->subQuarterNoOverflow()->lastOfQuarter()->format('Y-m-d')], + EmailStatement::THIS_QUARTER => [now()->startOfDay()->startOfQuarter()->format('Y-m-d'), now()->startOfDay()->endOfQuarter()->format('Y-m-d')], + EmailStatement::LAST_QUARTER => [now()->startOfDay()->subQuarterNoOverflow()->startOfQuarter()->format('Y-m-d'), now()->startOfDay()->subQuarterNoOverflow()->endOfQuarter()->format('Y-m-d')], EmailStatement::THIS_YEAR => [now()->startOfDay()->firstOfYear()->format('Y-m-d'), now()->startOfDay()->lastOfYear()->format('Y-m-d')], EmailStatement::LAST_YEAR => [now()->startOfDay()->subYearNoOverflow()->firstOfYear()->format('Y-m-d'), now()->startOfDay()->subYearNoOverflow()->lastOfYear()->format('Y-m-d')], EmailStatement::ALL_TIME => [ diff --git a/app/Utils/Traits/MakesDates.php b/app/Utils/Traits/MakesDates.php index 1c9a213c7d0d..ec8871ce48fa 100644 --- a/app/Utils/Traits/MakesDates.php +++ b/app/Utils/Traits/MakesDates.php @@ -153,8 +153,8 @@ trait MakesDates EmailStatement::LAST365 => [now()->startOfDay()->subDays(365)->format('Y-m-d'), now()->startOfDay()->format('Y-m-d')], EmailStatement::THIS_MONTH => [now()->startOfDay()->firstOfMonth()->format('Y-m-d'), now()->startOfDay()->lastOfMonth()->format('Y-m-d')], EmailStatement::LAST_MONTH => [now()->startOfDay()->subMonthNoOverflow()->firstOfMonth()->format('Y-m-d'), now()->startOfDay()->subMonthNoOverflow()->lastOfMonth()->format('Y-m-d')], - EmailStatement::THIS_QUARTER => [now()->startOfDay()->firstOfQuarter()->format('Y-m-d'), now()->startOfDay()->lastOfQuarter()->format('Y-m-d')], - EmailStatement::LAST_QUARTER => [now()->startOfDay()->subQuarterNoOverflow()->firstOfQuarter()->format('Y-m-d'), now()->startOfDay()->subQuarterNoOverflow()->lastOfQuarter()->format('Y-m-d')], + EmailStatement::THIS_QUARTER => [now()->startOfDay()->startOfQuarter()->format('Y-m-d'), now()->startOfDay()->endOfQuarter()->format('Y-m-d')], + EmailStatement::LAST_QUARTER => [now()->startOfDay()->subQuarterNoOverflow()->startOfQuarter()->format('Y-m-d'), now()->startOfDay()->subQuarterNoOverflow()->endOfQuarter()->format('Y-m-d')], EmailStatement::THIS_YEAR => [$fin_year_start->format('Y-m-d'), $fin_year_start->copy()->addYear()->subDay()->format('Y-m-d')], EmailStatement::LAST_YEAR => [$fin_year_start->format('Y-m-d'), $fin_year_start->copy()->addYear()->subDay()->format('Y-m-d')], EmailStatement::CUSTOM_RANGE => [$data['start_date'], $data['end_date']], From 4b397b5b3929385c0456c0048cfb0ada4e2b59a2 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 9 May 2024 11:42:52 +1000 Subject: [PATCH 2/6] Updates for expense filters --- app/Filters/ExpenseFilters.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/Filters/ExpenseFilters.php b/app/Filters/ExpenseFilters.php index c3efee2535c0..6c580cb719cb 100644 --- a/app/Filters/ExpenseFilters.php +++ b/app/Filters/ExpenseFilters.php @@ -107,6 +107,12 @@ class ExpenseFilters extends QueryFilters $query->whereNull('payment_date'); }); } + + if(in_array('uncategorized', $status_parameters)){ + $query->orWhere(function ($query){ + $query->whereNull('category_id'); + }); + } }); // nlog($this->builder->toSql()); @@ -200,7 +206,7 @@ class ExpenseFilters extends QueryFilters return $this->builder->orderByRaw("REGEXP_REPLACE(number,'[^0-9]+','')+0 " . $dir); } - if (is_array($sort_col) && in_array($sort_col[1], ['asc', 'desc']) && in_array($sort_col[0], ['public_notes', 'date', 'id_number', 'custom_value1', 'custom_value2', 'custom_value3', 'custom_value4'])) { + if (is_array($sort_col) && in_array($sort_col[1], ['asc', 'desc']) && in_array($sort_col[0], ['amount', 'public_notes', 'date', 'id_number', 'custom_value1', 'custom_value2', 'custom_value3', 'custom_value4'])) { return $this->builder->orderBy($sort_col[0], $sort_col[1]); } From a18806f986080478cd11d4ced2b26cd73b546793 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 9 May 2024 17:23:34 +1000 Subject: [PATCH 3/6] Fixes for tests --- app/Repositories/TaskRepository.php | 26 +++++++--- tests/Unit/TaskRoundingTest.php | 73 +++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 6 deletions(-) diff --git a/app/Repositories/TaskRepository.php b/app/Repositories/TaskRepository.php index 1778c83ea86e..1fd7bc7f5723 100644 --- a/app/Repositories/TaskRepository.php +++ b/app/Repositories/TaskRepository.php @@ -113,7 +113,7 @@ class TaskRepository extends BaseRepository foreach($time_log as $key => $value) { - $time_log[$key][1] = $this->roundTimeLog($time_log[$key][1]); + $time_log[$key][1] = $this->roundTimeLog($time_log[$key][0], $time_log[$key][1]); } if (isset($data['action'])) { @@ -252,17 +252,31 @@ class TaskRepository extends BaseRepository return $task; } - public function roundTimeLog(int $end_time): int + public function roundTimeLog(int $start_time, int $end_time): int { if($this->task_round_to_nearest == 1) return $end_time; - if($this->task_round_up) - return (int)ceil($end_time/$this->task_round_to_nearest)*$this->task_round_to_nearest; + $interval = $end_time - $start_time; + + if($this->task_round_up) + return $start_time + (int)ceil($interval/$this->task_round_to_nearest)*$this->task_round_to_nearest; + + return $start_time - (int)floor($interval/$this->task_round_to_nearest) * $this->task_round_to_nearest; - return (int)floor($end_time/$this->task_round_to_nearest) * $this->task_round_to_nearest; } + // public function roundTimeLog(int $end_time): int + // { + // if($this->task_round_to_nearest == 1) + // return $end_time; + + // if($this->task_round_up) + // return (int)ceil($end_time/$this->task_round_to_nearest)*$this->task_round_to_nearest; + + // return (int)floor($end_time/$this->task_round_to_nearest) * $this->task_round_to_nearest; + // } + public function stop(Task $task) { $this->init($task); @@ -272,7 +286,7 @@ class TaskRepository extends BaseRepository $last = end($log); if (is_array($last) && $last[1] === 0) { - $last[1] = $this->roundTimeLog(time()); + $last[1] = $this->roundTimeLog($last[0], time()); array_pop($log); $log = array_merge($log, [$last]);//check at this point, it may be prepending here. diff --git a/tests/Unit/TaskRoundingTest.php b/tests/Unit/TaskRoundingTest.php index 4ace3afa45df..96a8e1a9c4db 100644 --- a/tests/Unit/TaskRoundingTest.php +++ b/tests/Unit/TaskRoundingTest.php @@ -42,6 +42,79 @@ class TaskRoundingTest extends TestCase } + public function testRoundUp2() + { + + + + $start_time = 1715237056; + $end_time = $start_time + 60*7; + $this->task_round_to_nearest = 600; + + $rounded = $start_time + 60*10; + + $this->assertEquals($rounded, $this->roundTimeLog($start_time, $end_time)); + + + } + + public function testRoundUp3() + { + + + $start_time = 1715213100; + $end_time = $start_time + 60*15; + $this->task_round_to_nearest = 900; + + $rounded = $start_time + 60*15; + + $this->assertEquals($rounded, $this->roundTimeLog($start_time, $end_time)); + + +$s = \Carbon\Carbon::createFromTimestamp($start_time); + +$e = \Carbon\Carbon::createFromTimestamp($end_time); + + $x = \Carbon\Carbon::createFromTimestamp($rounded); + + +// echo $s->format('Y-m-d H:i:s').PHP_EOL; +// echo $e->format('Y-m-d H:i:s').PHP_EOL; +// echo $x->format('Y-m-d H:i:s').PHP_EOL; + + + } + +// public function testRoundUp4() +// { + + + +// $start_time = 1715238900; +// $end_time = 1715238000; +// // $end_time = $start_time + 60*15; +// $this->task_round_to_nearest = 900; + +// $rounded = $start_time + 60*15; + +// $this->assertEquals($rounded, $this->roundTimeLog($start_time, $end_time)); + + +// $s = \Carbon\Carbon::createFromTimestamp($start_time); + +// $e = \Carbon\Carbon::createFromTimestamp($end_time); + +// $x = \Carbon\Carbon::createFromTimestamp($rounded); + + +// echo $s->format('Y-m-d H:i:s').PHP_EOL; +// echo $e->format('Y-m-d H:i:s').PHP_EOL; +// echo $x->format('Y-m-d H:i:s').PHP_EOL; + + +// } + + public function testRoundDown() { $start_time = 1714942800; From 01dde73e95ad213b8718a623d4ee392f5700b608 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Fri, 10 May 2024 07:19:52 +1000 Subject: [PATCH 4/6] Fixes for rounding --- app/Http/Controllers/TaskController.php | 10 -- app/Repositories/TaskRepository.php | 15 +-- tests/Unit/TaskRoundingTest.php | 117 ++++++++++++++++++------ 3 files changed, 93 insertions(+), 49 deletions(-) diff --git a/app/Http/Controllers/TaskController.php b/app/Http/Controllers/TaskController.php index 4ce5bd79b164..f36c78de7bba 100644 --- a/app/Http/Controllers/TaskController.php +++ b/app/Http/Controllers/TaskController.php @@ -537,16 +537,6 @@ class TaskController extends BaseController return $this->listResponse(Task::withTrashed()->whereIn('id', $this->transformKeys($ids))); } - /** - * Returns a client statement. - * - * @return void [type] [description] - */ - public function statement() - { - //todo - } - /** * Update the specified resource in storage. * diff --git a/app/Repositories/TaskRepository.php b/app/Repositories/TaskRepository.php index 1fd7bc7f5723..2eb402d097b5 100644 --- a/app/Repositories/TaskRepository.php +++ b/app/Repositories/TaskRepository.php @@ -254,11 +254,11 @@ class TaskRepository extends BaseRepository public function roundTimeLog(int $start_time, int $end_time): int { - if($this->task_round_to_nearest == 1) + if($this->task_round_to_nearest == 1 || $end_time == 0) return $end_time; $interval = $end_time - $start_time; - + if($this->task_round_up) return $start_time + (int)ceil($interval/$this->task_round_to_nearest)*$this->task_round_to_nearest; @@ -266,17 +266,6 @@ class TaskRepository extends BaseRepository } - // public function roundTimeLog(int $end_time): int - // { - // if($this->task_round_to_nearest == 1) - // return $end_time; - - // if($this->task_round_up) - // return (int)ceil($end_time/$this->task_round_to_nearest)*$this->task_round_to_nearest; - - // return (int)floor($end_time/$this->task_round_to_nearest) * $this->task_round_to_nearest; - // } - public function stop(Task $task) { $this->init($task); diff --git a/tests/Unit/TaskRoundingTest.php b/tests/Unit/TaskRoundingTest.php index 96a8e1a9c4db..929d6628f475 100644 --- a/tests/Unit/TaskRoundingTest.php +++ b/tests/Unit/TaskRoundingTest.php @@ -12,6 +12,14 @@ namespace Tests\Unit; use Tests\TestCase; +use App\Models\Task; +use App\Models\Client; +use Tests\MockAccountData; +use App\Utils\Traits\MakesHash; +use App\DataMapper\ClientSettings; +use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Facades\Session; +use Illuminate\Foundation\Testing\DatabaseTransactions; /** * @test @@ -23,10 +31,23 @@ class TaskRoundingTest extends TestCase public bool $task_round_up = true; - protected function setUp(): void + use MakesHash; + use DatabaseTransactions; + use MockAccountData; + + private $faker; + + protected function setUp() :void { parent::setUp(); + $this->makeTestData(); + + Session::start(); + + $this->faker = \Faker\Factory::create(); + + Model::reguard(); } public function testRoundUp() @@ -70,50 +91,94 @@ class TaskRoundingTest extends TestCase $this->assertEquals($rounded, $this->roundTimeLog($start_time, $end_time)); + // $s = \Carbon\Carbon::createFromTimestamp($start_time); + // $e = \Carbon\Carbon::createFromTimestamp($end_time); + // $x = \Carbon\Carbon::createFromTimestamp($rounded); + // echo $s->format('Y-m-d H:i:s').PHP_EOL; + // echo $e->format('Y-m-d H:i:s').PHP_EOL; + // echo $x->format('Y-m-d H:i:s').PHP_EOL; -$s = \Carbon\Carbon::createFromTimestamp($start_time); + } -$e = \Carbon\Carbon::createFromTimestamp($end_time); + public function testRoundUp4() + { + + $start_time = 1715238000; + $end_time = 1715238900; - $x = \Carbon\Carbon::createFromTimestamp($rounded); + $this->task_round_to_nearest = 900; + + $rounded = $start_time + 60*15; + + // $s = \Carbon\Carbon::createFromTimestamp($start_time); + // $e = \Carbon\Carbon::createFromTimestamp($end_time); + // $x = \Carbon\Carbon::createFromTimestamp($rounded); + // echo $s->format('Y-m-d H:i:s').PHP_EOL; + // echo $e->format('Y-m-d H:i:s').PHP_EOL; + // echo $x->format('Y-m-d H:i:s').PHP_EOL; -// echo $s->format('Y-m-d H:i:s').PHP_EOL; -// echo $e->format('Y-m-d H:i:s').PHP_EOL; -// echo $x->format('Y-m-d H:i:s').PHP_EOL; +$this->assertEquals($rounded, $this->roundTimeLog($start_time, $end_time)); } -// public function testRoundUp4() -// { - + public function testRoundingViaBulkAction() + { + + $this->company->settings->default_task_rate = 41; + $this->company->settings->task_round_to_nearest = 900; + $this->company->settings->task_round_up = true; + $this->company->saveSettings($this->company->settings, $this->company); + + $settings = ClientSettings::defaults(); + $settings->default_task_rate = 41; + $settings->task_round_to_nearest = 900; + $settings->task_round_up = true; + + $c = Client::factory()->create([ + 'user_id' => $this->user->id, + 'company_id' => $this->company->id, + // 'settings' => $settings, + ]); -// $start_time = 1715238900; -// $end_time = 1715238000; -// // $end_time = $start_time + 60*15; -// $this->task_round_to_nearest = 900; + $var = time()-800; -// $rounded = $start_time + 60*15; + $data = [ + 'client_id' => $c->hashed_id, + 'description' => 'Test Task', + 'time_log' => '[[1681165417,1681165432,"sumtin",true],['.$var.',0]]', + 'assigned_user' => [], + 'project' => [], + 'user' => [], + ]; -// $this->assertEquals($rounded, $this->roundTimeLog($start_time, $end_time)); + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->postJson("/api/v1/tasks/", $data); + $response->assertStatus(200); + $arr = $response->json(); -// $s = \Carbon\Carbon::createFromTimestamp($start_time); + $i = $arr['data']['id']; -// $e = \Carbon\Carbon::createFromTimestamp($end_time); + $data = [ + 'ids' => [$i], + 'action' => 'stop' + ]; -// $x = \Carbon\Carbon::createFromTimestamp($rounded); + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->postJson("/api/v1/tasks/bulk", $data); + $response->assertStatus(200); + $arr = $response->json(); -// echo $s->format('Y-m-d H:i:s').PHP_EOL; -// echo $e->format('Y-m-d H:i:s').PHP_EOL; -// echo $x->format('Y-m-d H:i:s').PHP_EOL; - - -// } - + $task = Task::find($this->decodePrimaryKey($i)); + } public function testRoundDown() { From a46a77049630791c404b5d6df22306acb54ec865 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Fri, 10 May 2024 20:05:36 +1000 Subject: [PATCH 5/6] Copy documents when converting a quote to an invoice --- app/Jobs/Document/CopyDocs.php | 85 +++++++++++++++++++++++++++++ app/Services/Client/Statement.php | 7 --- app/Services/Quote/ConvertQuote.php | 16 ++++-- 3 files changed, 95 insertions(+), 13 deletions(-) create mode 100644 app/Jobs/Document/CopyDocs.php diff --git a/app/Jobs/Document/CopyDocs.php b/app/Jobs/Document/CopyDocs.php new file mode 100644 index 000000000000..98e5003a8d21 --- /dev/null +++ b/app/Jobs/Document/CopyDocs.php @@ -0,0 +1,85 @@ +db); + + Document::whereIn('id', $this->document_ids) + ->where('company_id', $this->entity->company_id) + ->each(function ($document){ + + $file = $document->getFile(); + + $extension = pathinfo($document->name, PATHINFO_EXTENSION); + + $new_hash = \Illuminate\Support\Str::random(32) . "." . $extension; + + Storage::disk($document->disk)->put( + "{$this->entity->company->company_key}/documents/{$new_hash}", + $file, + ); + + $instance = Storage::disk($document->disk)->path("{$this->entity->company->company_key}/documents/{$new_hash}"); + + $new_doc = new Document(); + $new_doc->user_id = $this->entity->user_id; + $new_doc->company_id = $this->entity->company_id; + $new_doc->url = $instance; + $new_doc->name = $document->name; + $new_doc->type = $extension; + $new_doc->disk = $document->disk; + $new_doc->hash = $new_hash; + $new_doc->size = $document->size; + $new_doc->width = $document->width; + $new_doc->height = $document->height; + $new_doc->is_public = $document->is_public; + + $this->entity->documents()->save($new_doc); + + }); + } + +} diff --git a/app/Services/Client/Statement.php b/app/Services/Client/Statement.php index 2118386d664f..8c4bea787849 100644 --- a/app/Services/Client/Statement.php +++ b/app/Services/Client/Statement.php @@ -103,13 +103,6 @@ class Statement ], \App\Services\PdfMaker\Design::STATEMENT), 'variables' => $variables, 'options' => [ - // 'client' => $this->client, - // 'entity' => $this->entity, - // 'variables' => $variables, - // 'invoices' => $this->getInvoices()->cursor(), - // 'payments' => $this->getPayments()->cursor(), - // 'credits' => $this->getCredits()->cursor(), - // 'aging' => $this->getAging(), ], 'process_markdown' => $this->entity->client->company->markdown_enabled, ]; diff --git a/app/Services/Quote/ConvertQuote.php b/app/Services/Quote/ConvertQuote.php index c0ce4abe1562..97c1e18e8641 100644 --- a/app/Services/Quote/ConvertQuote.php +++ b/app/Services/Quote/ConvertQuote.php @@ -12,13 +12,15 @@ namespace App\Services\Quote; -use App\Factory\CloneQuoteToInvoiceFactory; -use App\Factory\InvoiceInvitationFactory; -use App\Models\Invoice; use App\Models\Quote; -use App\Repositories\InvoiceRepository; -use App\Utils\Traits\GeneratesConvertedQuoteCounter; +use App\Models\Invoice; +use App\Jobs\Util\UploadFile; use App\Utils\Traits\MakesHash; +use App\Repositories\InvoiceRepository; +use App\Factory\InvoiceInvitationFactory; +use App\Factory\CloneQuoteToInvoiceFactory; +use App\Jobs\Document\CopyDocs; +use App\Utils\Traits\GeneratesConvertedQuoteCounter; class ConvertQuote { @@ -73,7 +75,9 @@ class ConvertQuote $quote->status_id = Quote::STATUS_CONVERTED; $quote->save(); - // maybe should return invoice here + if($quote->documents()->count() > 0) + CopyDocs::dispatch($quote->documents()->pluck('id'), $invoice, $invoice->company->db); + return $invoice; } From 83605482d9e881430c1149cf86d1d4abd37bbce8 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Fri, 10 May 2024 21:32:14 +1000 Subject: [PATCH 6/6] Fixes for purchase order edoc export --- app/Jobs/EDocument/CreateEDocument.php | 4 ++-- app/Services/EDocument/Standards/OrderXDocument.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/Jobs/EDocument/CreateEDocument.php b/app/Jobs/EDocument/CreateEDocument.php index a97d8f20b8dc..c2e0b5a16f25 100644 --- a/app/Jobs/EDocument/CreateEDocument.php +++ b/app/Jobs/EDocument/CreateEDocument.php @@ -59,11 +59,11 @@ class CreateEDocument implements ShouldQueue App::setLocale($settings_entity->locale()); /* Set customized translations _NOW_ */ - $t->replace(Ninja::transformTranslations($this->document->client->getMergedSettings())); + if($this->document->client ?? false) + $t->replace(Ninja::transformTranslations($this->document->client->getMergedSettings())); $e_document_type = strlen($settings_entity->getSetting('e_invoice_type')) > 2 ? $settings_entity->getSetting('e_invoice_type') : "XInvoice_3_0"; $e_quote_type = strlen($settings_entity->getSetting('e_quote_type')) > 2 ? $settings_entity->getSetting('e_quote_type') : "OrderX_Extended"; -nlog($e_document_type); if ($this->document instanceof Invoice){ switch ($e_document_type) { diff --git a/app/Services/EDocument/Standards/OrderXDocument.php b/app/Services/EDocument/Standards/OrderXDocument.php index c62f6494a993..71349db49595 100644 --- a/app/Services/EDocument/Standards/OrderXDocument.php +++ b/app/Services/EDocument/Standards/OrderXDocument.php @@ -51,7 +51,7 @@ class OrderXDocument extends AbstractService ->setDocumentSellerAddress($company->getSetting("address1"), $company->getSetting("address2"), "", $company->getSetting("postal_code"), $company->getSetting("city"), $company->country()->iso_3166_2, $company->getSetting("state")) ->setDocumentSellerContact($this->document->user->present()->getFullName(), "", $this->document->user->present()->phone(), "", $this->document->user->email) ->setDocumentBuyer($settings_entity->present()->name(), $settings_entity->number) - ->setDocumentBuyerAddress($settings_entity->address1, "", "", $settings_entity->postal_code, $settings_entity->city, $settings_entity->country->iso_3166_2, $settings_entity->state) + ->setDocumentBuyerAddress($settings_entity->address1, "", "", $settings_entity->postal_code, $settings_entity->city, $settings_entity->country->iso_3166_2 ?? $company->country()->iso_3166_2, $settings_entity->state) ->setDocumentBuyerContact($settings_entity->present()->primary_contact_name(), "", $settings_entity->present()->phone(), "", $settings_entity->present()->email()) ->addDocumentPaymentTerm(ctrans("texts.xinvoice_payable", ['payeddue' => date_create($this->document->date ?? now()->format('Y-m-d'))->diff(date_create($this->document->due_date ?? now()->format('Y-m-d')))->format("%d"), 'paydate' => $this->document->due_date]));