diff --git a/VERSION.txt b/VERSION.txt index dbf3366489b1..c9c84322d739 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -5.0.22 +5.0.23 diff --git a/app/Http/Requests/Task/StoreTaskRequest.php b/app/Http/Requests/Task/StoreTaskRequest.php index 78cf87402e94..6bd1bce41387 100644 --- a/app/Http/Requests/Task/StoreTaskRequest.php +++ b/app/Http/Requests/Task/StoreTaskRequest.php @@ -38,8 +38,8 @@ class StoreTaskRequest extends Request { $rules = []; - $rules['number'] = Rule::unique('tasks') - ->where('company_id', auth()->user()->company()->id); + if(isset($this->number)) + $rules['number'] = Rule::unique('tasks')->where('company_id', auth()->user()->company()->id); return $this->globalRules($rules); } diff --git a/app/Http/Requests/Task/UpdateTaskRequest.php b/app/Http/Requests/Task/UpdateTaskRequest.php index 57fcda98bb9c..16a1e3882e1f 100644 --- a/app/Http/Requests/Task/UpdateTaskRequest.php +++ b/app/Http/Requests/Task/UpdateTaskRequest.php @@ -38,9 +38,8 @@ class UpdateTaskRequest extends Request { $rules = []; - $rules['number'] = Rule::unique('tasks') - ->where('company_id', auth()->user()->company()->id) - ->ignore($this->task->id); + if(isset($this->number)) + $rules['number'] = Rule::unique('tasks')->where('company_id', auth()->user()->company()->id)->ignore($this->task->id); return $this->globalRules($rules); } diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php index 1fc5e4d7084d..d850444409f3 100644 --- a/app/Models/Invoice.php +++ b/app/Models/Invoice.php @@ -209,6 +209,15 @@ class Invoice extends BaseModel return $this->hasMany(Credit::class); } + public function tasks() + { + return $this->hasMany(Task::class); + } + + public function expenses() + { + return $this->hasMany(Expense::class); + } /** * Service entry points. */ diff --git a/app/Repositories/BaseRepository.php b/app/Repositories/BaseRepository.php index 510decebc161..8a586923e4b8 100644 --- a/app/Repositories/BaseRepository.php +++ b/app/Repositories/BaseRepository.php @@ -314,6 +314,7 @@ class BaseRepository if (($state['finished_amount'] != $state['starting_amount']) && ($model->status_id != Invoice::STATUS_DRAFT)) { $model->ledger()->updateInvoiceBalance(($state['finished_amount'] - $state['starting_amount'])); $model->client->service()->updateBalance(($state['finished_amount'] - $state['starting_amount']))->save(); + $model->service()->linkEntities()->save(); } if (! $model->design_id) { diff --git a/app/Services/Invoice/InvoiceService.php b/app/Services/Invoice/InvoiceService.php index da1393e21409..0a17c929ea44 100644 --- a/app/Services/Invoice/InvoiceService.php +++ b/app/Services/Invoice/InvoiceService.php @@ -14,8 +14,10 @@ namespace App\Services\Invoice; use App\Jobs\Entity\CreateEntityPdf; use App\Jobs\Util\UnlinkFile; use App\Models\CompanyGateway; +use App\Models\Expense; use App\Models\Invoice; use App\Models\Payment; +use App\Models\Task; use App\Services\Client\ClientService; use App\Services\Invoice\ApplyNumber; use App\Services\Invoice\ApplyPayment; @@ -30,10 +32,13 @@ use App\Services\Invoice\MarkInvoicePaid; use App\Services\Invoice\MarkSent; use App\Services\Invoice\TriggeredActions; use App\Services\Invoice\UpdateBalance; +use App\Utils\Traits\MakesHash; use Illuminate\Support\Carbon; class InvoiceService { + use MakesHash; + private $invoice; protected $client_service; @@ -328,6 +333,30 @@ class InvoiceService return $this; } + public function linkEntities() + { + //set all task.invoice_ids = 0 + $this->invoice->tasks()->update(['invoice_id' => null]); + + //set all tasks.invoice_ids = x with the current line_items + $tasks = collect($this->invoice->line_items)->map(function ($item){ + + if(isset($item->task_id)) + $item->task_id = $this->decodePrimaryKey($item->task_id); + + if(isset($item->expense_id)) + $item->expense_id = $this->decodePrimaryKey($item->expense_id); + + return $item; + + }); + + Task::whereIn('id',$tasks->pluck('task_id'))->update(['invoice_id' => $this->invoice->id]); + Expense::whereIn('id',$tasks->pluck('expense_id'))->update(['invoice_id' => $this->invoice->id]); + + return $this; + } + /** * Saves the invoice. * @return Invoice object diff --git a/app/Services/Invoice/MarkInvoiceDeleted.php b/app/Services/Invoice/MarkInvoiceDeleted.php index 2d98ed2ed4fb..7d245d64b487 100644 --- a/app/Services/Invoice/MarkInvoiceDeleted.php +++ b/app/Services/Invoice/MarkInvoiceDeleted.php @@ -53,6 +53,10 @@ class MarkInvoiceDeleted extends AbstractService $this->invoice->number = $number; + //wipe references to invoices from related entities. + $this->invoice->tasks()->update(['invoice_id' => null]); + $this->invoice->expenses()->update(['invoice_id' => null]); + return $this->invoice; } diff --git a/app/Utils/Traits/Notifications/UserNotifies.php b/app/Utils/Traits/Notifications/UserNotifies.php index 7ff3b0a1cf60..7a9f7c22b38c 100644 --- a/app/Utils/Traits/Notifications/UserNotifies.php +++ b/app/Utils/Traits/Notifications/UserNotifies.php @@ -41,7 +41,7 @@ trait UserNotifies public function findUserEntityNotificationType($entity, $company_user, $required_permissions) :array { - if ($this->migrationRunning($company_user)) { + if ($company_user->company->is_disabled) { return []; } @@ -65,7 +65,7 @@ trait UserNotifies public function findCompanyUserNotificationType($company_user, $required_permissions) :array { - if ($this->migrationRunning($company_user)) { + if ($company_user->company->is_disabled) { return []; } diff --git a/config/ninja.php b/config/ninja.php index 2ea9e28e7557..a304af58b545 100644 --- a/config/ninja.php +++ b/config/ninja.php @@ -12,7 +12,7 @@ return [ 'require_https' => env('REQUIRE_HTTPS', true), 'app_url' => rtrim(env('APP_URL', ''), '/').'/', 'app_domain' => env('APP_DOMAIN', ''), - 'app_version' => '5.0.22', + 'app_version' => '5.0.23', 'minimum_client_version' => '5.0.16', 'terms_version' => '1.0.1', 'api_secret' => env('API_SECRET', ''), diff --git a/database/factories/ExpenseFactory.php b/database/factories/ExpenseFactory.php index ea5716ca6402..685bead9803e 100644 --- a/database/factories/ExpenseFactory.php +++ b/database/factories/ExpenseFactory.php @@ -42,6 +42,7 @@ class ExpenseFactory extends Factory 'public_notes' => $this->faker->text(50), 'private_notes' => $this->faker->text(50), 'transaction_reference' => $this->faker->text(5), + 'invoice_id' => null, ]; } } diff --git a/database/factories/TaskFactory.php b/database/factories/TaskFactory.php index 759114c9d8f2..b18016f3e14a 100644 --- a/database/factories/TaskFactory.php +++ b/database/factories/TaskFactory.php @@ -33,6 +33,7 @@ class TaskFactory extends Factory { return [ 'description' => $this->faker->text(50), + 'invoice_id' => null, ]; } } \ No newline at end of file diff --git a/tests/Feature/InvoiceLinkTasksTest.php b/tests/Feature/InvoiceLinkTasksTest.php new file mode 100644 index 000000000000..3a2c7b1eed84 --- /dev/null +++ b/tests/Feature/InvoiceLinkTasksTest.php @@ -0,0 +1,77 @@ +faker = \Faker\Factory::create(); + + Model::reguard(); + + $this->makeTestData(); + } + + public function testMapCreation() + { + $temp_invoice_id = $this->invoice->id; + + $tasks = collect($this->invoice->line_items)->map(function ($item){ + + if(isset($item->task_id)) + $item->task_id = $this->decodePrimaryKey($item->task_id); + + if(isset($item->expense_id)) + $item->expense_id = $this->decodePrimaryKey($item->expense_id); + + return $item; + + }); + + $this->assertEquals($tasks->first()->task_id, $this->task->id); + $this->assertEquals($tasks->first()->expense_id, $this->expense->id); + + $this->invoice = $this->invoice->service()->linkEntities()->save(); + + $this->assertEquals($this->task->fresh()->invoice_id, $temp_invoice_id); + $this->assertEquals($this->expense->fresh()->invoice_id, $temp_invoice_id); + } +} diff --git a/tests/MockAccountData.php b/tests/MockAccountData.php index df2a56a3cf3d..6d6461e1e7d3 100644 --- a/tests/MockAccountData.php +++ b/tests/MockAccountData.php @@ -570,6 +570,8 @@ trait MockAccountData $item = InvoiceItemFactory::create(); $item->quantity = 1; $item->cost = 10; + $item->task_id = $this->encodePrimaryKey($this->task->id); + $item->expense_id = $this->encodePrimaryKey($this->expense->id); $line_items[] = $item;