mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-31 10:24:35 -04:00
Start and Stop Recurring Expenses
This commit is contained in:
parent
6200f572e6
commit
65bc26ab79
@ -12,12 +12,14 @@
|
|||||||
namespace App\Factory;
|
namespace App\Factory;
|
||||||
|
|
||||||
use App\Models\RecurringExpense;
|
use App\Models\RecurringExpense;
|
||||||
|
use App\Models\RecurringInvoice;
|
||||||
|
|
||||||
class RecurringExpenseFactory
|
class RecurringExpenseFactory
|
||||||
{
|
{
|
||||||
public static function create(int $company_id, int $user_id) :RecurringExpense
|
public static function create(int $company_id, int $user_id) :RecurringExpense
|
||||||
{
|
{
|
||||||
$recurring_expense = new RecurringExpense();
|
$recurring_expense = new RecurringExpense();
|
||||||
|
$recurring_expense->status_id = RecurringInvoice::STATUS_DRAFT;
|
||||||
$recurring_expense->user_id = $user_id;
|
$recurring_expense->user_id = $user_id;
|
||||||
$recurring_expense->company_id = $company_id;
|
$recurring_expense->company_id = $company_id;
|
||||||
$recurring_expense->is_deleted = false;
|
$recurring_expense->is_deleted = false;
|
||||||
|
@ -495,21 +495,59 @@ class RecurringExpenseController extends BaseController
|
|||||||
|
|
||||||
$recurring_expenses->each(function ($recurring_expense, $key) use ($action) {
|
$recurring_expenses->each(function ($recurring_expense, $key) use ($action) {
|
||||||
if (auth()->user()->can('edit', $recurring_expense)) {
|
if (auth()->user()->can('edit', $recurring_expense)) {
|
||||||
$this->recurring_expense_repo->{$action}($recurring_expense);
|
$this->performAction($recurring_expense, $action, true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return $this->listResponse(RecurringExpense::withTrashed()->whereIn('id', $this->transformKeys($ids)));
|
return $this->listResponse(RecurringExpense::withTrashed()->whereIn('id', $this->transformKeys($ids)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private function performAction(RecurringExpense $recurring_expense, string $action, $bulk = false)
|
||||||
* Returns a client statement.
|
|
||||||
*
|
|
||||||
* @return void [type] [description]
|
|
||||||
*/
|
|
||||||
public function statement()
|
|
||||||
{
|
{
|
||||||
//todo
|
switch ($action) {
|
||||||
|
case 'archive':
|
||||||
|
$this->recurring_expense_repo->archive($recurring_expense);
|
||||||
|
|
||||||
|
if (! $bulk) {
|
||||||
|
return $this->listResponse($recurring_expense);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'restore':
|
||||||
|
$this->recurring_expense_repo->restore($recurring_expense);
|
||||||
|
|
||||||
|
if (! $bulk) {
|
||||||
|
return $this->listResponse($recurring_expense);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'delete':
|
||||||
|
$this->recurring_expense_repo->delete($recurring_expense);
|
||||||
|
|
||||||
|
if (! $bulk) {
|
||||||
|
return $this->listResponse($recurring_expense);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'email':
|
||||||
|
//dispatch email to queue
|
||||||
|
break;
|
||||||
|
case 'start':
|
||||||
|
$recurring_expense = $recurring_expense->service()->start()->save();
|
||||||
|
|
||||||
|
if (! $bulk) {
|
||||||
|
$this->itemResponse($recurring_expense);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'stop':
|
||||||
|
$recurring_expense = $recurring_expense->service()->stop()->save();
|
||||||
|
|
||||||
|
if (! $bulk) {
|
||||||
|
$this->itemResponse($recurring_expense);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// code...
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -31,7 +31,6 @@ use App\Utils\Ninja;
|
|||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
use App\Utils\Traits\SavesDocuments;
|
use App\Utils\Traits\SavesDocuments;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Services\Recurring\RecurringService;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
class RecurringExpense extends BaseModel
|
class RecurringExpense extends BaseModel
|
||||||
@ -105,4 +106,12 @@ class RecurringExpense extends BaseModel
|
|||||||
{
|
{
|
||||||
return $this->belongsTo(Client::class);
|
return $this->belongsTo(Client::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service entry points.
|
||||||
|
*/
|
||||||
|
public function service() :RecurringService
|
||||||
|
{
|
||||||
|
return new RecurringService($this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -180,6 +180,10 @@ use App\Listeners\Quote\QuoteRestoredActivity;
|
|||||||
use App\Listeners\Quote\QuoteViewedActivity;
|
use App\Listeners\Quote\QuoteViewedActivity;
|
||||||
use App\Listeners\Quote\ReachWorkflowSettings;
|
use App\Listeners\Quote\ReachWorkflowSettings;
|
||||||
use App\Listeners\RecurringExpense\CreatedRecurringExpenseActivity;
|
use App\Listeners\RecurringExpense\CreatedRecurringExpenseActivity;
|
||||||
|
use App\Listeners\RecurringExpense\RecurringExpenseArchivedActivity;
|
||||||
|
use App\Listeners\RecurringExpense\RecurringExpenseDeletedActivity;
|
||||||
|
use App\Listeners\RecurringExpense\RecurringExpenseRestoredActivity;
|
||||||
|
use App\Listeners\RecurringExpense\RecurringExpenseUpdatedActivity;
|
||||||
use App\Listeners\RecurringInvoice\CreateRecurringInvoiceActivity;
|
use App\Listeners\RecurringInvoice\CreateRecurringInvoiceActivity;
|
||||||
use App\Listeners\RecurringInvoice\RecurringInvoiceArchivedActivity;
|
use App\Listeners\RecurringInvoice\RecurringInvoiceArchivedActivity;
|
||||||
use App\Listeners\RecurringInvoice\RecurringInvoiceDeletedActivity;
|
use App\Listeners\RecurringInvoice\RecurringInvoiceDeletedActivity;
|
||||||
|
@ -53,6 +53,7 @@ class RecurringExpenseTransformer extends EntityTransformer
|
|||||||
'id' => $this->encodePrimaryKey($recurring_expense->id),
|
'id' => $this->encodePrimaryKey($recurring_expense->id),
|
||||||
'user_id' => $this->encodePrimaryKey($recurring_expense->user_id),
|
'user_id' => $this->encodePrimaryKey($recurring_expense->user_id),
|
||||||
'assigned_user_id' => $this->encodePrimaryKey($recurring_expense->assigned_user_id),
|
'assigned_user_id' => $this->encodePrimaryKey($recurring_expense->assigned_user_id),
|
||||||
|
'status_id' => (string) ($recurring_expense->status_id ?: 1),
|
||||||
'vendor_id' => $this->encodePrimaryKey($recurring_expense->vendor_id),
|
'vendor_id' => $this->encodePrimaryKey($recurring_expense->vendor_id),
|
||||||
'invoice_id' => $this->encodePrimaryKey($recurring_expense->invoice_id),
|
'invoice_id' => $this->encodePrimaryKey($recurring_expense->invoice_id),
|
||||||
'client_id' => $this->encodePrimaryKey($recurring_expense->client_id),
|
'client_id' => $this->encodePrimaryKey($recurring_expense->client_id),
|
||||||
|
@ -22,6 +22,7 @@ class RecurringExpensesSchema extends Migration
|
|||||||
$table->unsignedInteger('company_id')->index();
|
$table->unsignedInteger('company_id')->index();
|
||||||
$table->unsignedInteger('vendor_id')->nullable();
|
$table->unsignedInteger('vendor_id')->nullable();
|
||||||
$table->unsignedInteger('user_id');
|
$table->unsignedInteger('user_id');
|
||||||
|
$table->unsignedInteger('status_id');
|
||||||
|
|
||||||
$table->unsignedInteger('invoice_id')->nullable();
|
$table->unsignedInteger('invoice_id')->nullable();
|
||||||
$table->unsignedInteger('client_id')->nullable();
|
$table->unsignedInteger('client_id')->nullable();
|
||||||
|
@ -10,13 +10,14 @@
|
|||||||
*/
|
*/
|
||||||
namespace Tests\Feature;
|
namespace Tests\Feature;
|
||||||
|
|
||||||
|
use App\Models\RecurringInvoice;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||||
use Illuminate\Support\Facades\Session;
|
use Illuminate\Support\Facades\Session;
|
||||||
|
use Illuminate\Validation\ValidationException;
|
||||||
use Tests\MockAccountData;
|
use Tests\MockAccountData;
|
||||||
use Tests\TestCase;
|
use Tests\TestCase;
|
||||||
use Illuminate\Validation\ValidationException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @test
|
* @test
|
||||||
@ -67,6 +68,7 @@ class RecurringExpenseApiTest extends TestCase
|
|||||||
'amount' => 10,
|
'amount' => 10,
|
||||||
'client_id' => $this->client->hashed_id,
|
'client_id' => $this->client->hashed_id,
|
||||||
'number' => '123321',
|
'number' => '123321',
|
||||||
|
'frequency_id' => 5,
|
||||||
];
|
];
|
||||||
|
|
||||||
$response = $this->withHeaders([
|
$response = $this->withHeaders([
|
||||||
@ -170,4 +172,44 @@ class RecurringExpenseApiTest extends TestCase
|
|||||||
|
|
||||||
$this->assertTrue($arr['data'][0]['is_deleted']);
|
$this->assertTrue($arr['data'][0]['is_deleted']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testRecurringExpenseStart()
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'ids' => [$this->encodePrimaryKey($this->recurring_expense->id)],
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->post('/api/v1/recurring_expenses/bulk?action=start', $data);
|
||||||
|
|
||||||
|
$arr = $response->json();
|
||||||
|
nlog($arr);
|
||||||
|
$this->assertEquals(RecurringInvoice::STATUS_ACTIVE, $arr['data'][0]['status_id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function testRecurringExpensePaused()
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'ids' => [$this->encodePrimaryKey($this->recurring_expense->id)],
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->post('/api/v1/recurring_expenses/bulk?action=start', $data);
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->post('/api/v1/recurring_expenses/bulk?action=stop', $data);
|
||||||
|
|
||||||
|
$arr = $response->json();
|
||||||
|
nlog($arr);
|
||||||
|
$this->assertEquals(RecurringInvoice::STATUS_PAUSED, $arr['data'][0]['status_id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -301,6 +301,8 @@ trait MockAccountData
|
|||||||
$this->recurring_expense = RecurringExpense::factory()->create([
|
$this->recurring_expense = RecurringExpense::factory()->create([
|
||||||
'user_id' => $user_id,
|
'user_id' => $user_id,
|
||||||
'company_id' => $this->company->id,
|
'company_id' => $this->company->id,
|
||||||
|
'frequency_id' => 5,
|
||||||
|
'remaining_cycles' => 5,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->recurring_quote = RecurringQuote::factory()->create([
|
$this->recurring_quote = RecurringQuote::factory()->create([
|
||||||
|
Loading…
x
Reference in New Issue
Block a user