Add bulk categorization:

This commit is contained in:
David Bomba 2023-11-03 11:07:05 +11:00
parent d26e5f05c3
commit 79e9c516fd
4 changed files with 127 additions and 50 deletions

View File

@ -11,27 +11,28 @@
namespace App\Http\Controllers;
use App\Events\Expense\ExpenseWasCreated;
use App\Events\Expense\ExpenseWasUpdated;
use App\Utils\Ninja;
use App\Models\Account;
use App\Models\Expense;
use Illuminate\Http\Response;
use App\Factory\ExpenseFactory;
use App\Filters\ExpenseFilters;
use App\Http\Requests\Expense\CreateExpenseRequest;
use App\Http\Requests\Expense\DestroyExpenseRequest;
use App\Utils\Traits\MakesHash;
use App\Utils\Traits\Uploadable;
use App\Utils\Traits\BulkOptions;
use App\Utils\Traits\SavesDocuments;
use App\Repositories\ExpenseRepository;
use App\Transformers\ExpenseTransformer;
use App\Events\Expense\ExpenseWasCreated;
use App\Events\Expense\ExpenseWasUpdated;
use App\Http\Requests\Expense\BulkExpenseRequest;
use App\Http\Requests\Expense\EditExpenseRequest;
use App\Http\Requests\Expense\ShowExpenseRequest;
use App\Http\Requests\Expense\StoreExpenseRequest;
use App\Http\Requests\Expense\CreateExpenseRequest;
use App\Http\Requests\Expense\UpdateExpenseRequest;
use App\Http\Requests\Expense\UploadExpenseRequest;
use App\Models\Account;
use App\Models\Expense;
use App\Repositories\ExpenseRepository;
use App\Transformers\ExpenseTransformer;
use App\Utils\Ninja;
use App\Utils\Traits\BulkOptions;
use App\Utils\Traits\MakesHash;
use App\Utils\Traits\SavesDocuments;
use App\Utils\Traits\Uploadable;
use Illuminate\Http\Response;
use App\Http\Requests\Expense\DestroyExpenseRequest;
/**
* Class ExpenseController.
@ -321,7 +322,10 @@ class ExpenseController extends BaseController
*/
public function create(CreateExpenseRequest $request)
{
$expense = ExpenseFactory::create(auth()->user()->company()->id, auth()->user()->id);
/** @var \App\Models\User $user */
$user = auth()->user();
$expense = ExpenseFactory::create($user->company()->id, $user->id);
return $this->itemResponse($expense);
}
@ -366,9 +370,12 @@ class ExpenseController extends BaseController
*/
public function store(StoreExpenseRequest $request)
{
$expense = $this->expense_repo->save($request->all(), ExpenseFactory::create(auth()->user()->company()->id, auth()->user()->id));
/** @var \App\Models\User $user */
$user = auth()->user();
event(new ExpenseWasCreated($expense, $expense->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
$expense = $this->expense_repo->save($request->all(), ExpenseFactory::create($user->company()->id, $user->id));
event(new ExpenseWasCreated($expense, $expense->company, Ninja::eventVars($user ? $user->id : null)));
event('eloquent.created: App\Models\Expense', $expense);
@ -481,20 +488,25 @@ class ExpenseController extends BaseController
* ),
* )
*/
public function bulk()
public function bulk(BulkExpenseRequest $request)
{
$action = request()->input('action');
/** @var \App\Models\User $user */
$user = auth()->user();
$ids = request()->input('ids');
$expenses = Expense::withTrashed()->find($this->transformKeys($ids));
$expenses = Expense::withTrashed()->find($request->ids);
$expenses->each(function ($expense, $key) use ($action) {
if (auth()->user()->can('edit', $expense)) {
$this->expense_repo->{$action}($expense);
if($request->action == 'bulk_categorize' && $user->can('edit', $expenses->first())) {
$this->expense_repo->categorize($expenses, $request->category_id);
$expenses = collect([]);
}
$expenses->each(function ($expense) use ($request, $user) {
if ($user->can('edit', $expense)) {
$this->expense_repo->{$request->action}($expense);
}
});
return $this->listResponse(Expense::withTrashed()->whereIn('id', $this->transformKeys($ids)));
return $this->listResponse(Expense::withTrashed()->whereIn('id', $request->ids));
}
/**

View File

@ -12,13 +12,10 @@
namespace App\Http\Requests\Expense;
use App\Http\Requests\Request;
use App\Models\Expense;
use App\Utils\Traits\BulkOptions;
use Illuminate\Validation\Rule;
class BulkExpenseRequest extends Request
{
use BulkOptions;
/**
* Determine if the user is authorized to make this request.
*
@ -26,15 +23,7 @@ class BulkExpenseRequest extends Request
*/
public function authorize()
{
if (! $this->has('action')) {
return false;
}
if (! in_array($this->action, $this->getBulkOptions(), true)) {
return false;
}
return auth()->user()->can(auth()->user()->isAdmin(), Expense::class);
return true;
}
/**
@ -44,13 +33,30 @@ class BulkExpenseRequest extends Request
*/
public function rules()
{
$rules = $this->getGlobalRules();
/** @var \App\Models\User $user */
$user = auth()->user();
/* We don't require IDs on bulk storing. */
if ($this->action !== self::$STORE_METHOD) {
$rules['ids'] = ['required'];
return [
'ids' => ['required','bail','array', Rule::exists('expenses', 'id')->where('company_id', $user->company()->id)],
'category_id' => ['sometimes', 'bail', Rule::exists('expense_categories', 'id')->where('company_id', $user->company()->id)],
'action' => 'in:archive,restore,delete,bulk_categorize',
];
}
public function prepareForValidation()
{
$input = $this->all();
if (isset($input['ids'])) {
$input['ids'] = $this->transformKeys($input['ids']);
}
return $rules;
if (isset($input['category_id'])) {
$input['category_id'] = $this->transformKeys($input['category_id']);
}
$this->replace($input);
}
}

View File

@ -12,13 +12,14 @@
namespace App\Repositories;
use App\Factory\ExpenseFactory;
use App\Libraries\Currency\Conversion\CurrencyApi;
use App\Models\Expense;
use App\Utils\Traits\GeneratesCounter;
use Carbon\Exceptions\InvalidFormatException;
use Illuminate\Database\QueryException;
use Illuminate\Support\Carbon;
use App\Factory\ExpenseFactory;
use App\Models\ExpenseCategory;
use App\Utils\Traits\GeneratesCounter;
use Illuminate\Database\QueryException;
use Carbon\Exceptions\InvalidFormatException;
use App\Libraries\Currency\Conversion\CurrencyApi;
/**
* ExpenseRepository.
@ -158,4 +159,25 @@ class ExpenseRepository extends BaseRepository
return $expense;
}
/**
* Categorize Expenses in bulk
*
* @param Collection $expenses
* @param int $category_id
* @return void
*/
public function categorize($expenses, $category_id): void
{
$ec = ExpenseCategory::withTrashed()->find($category_id);
$expenses->when($ec)
->each(function ($expense) use($ec){
$expense->category_id = $ec->id;
$expense->save();
});
}
}

View File

@ -11,11 +11,12 @@
namespace Tests\Feature;
use App\Models\BankIntegration;
use App\Models\BankTransaction;
use Tests\TestCase;
use App\Models\Expense;
use Tests\MockAccountData;
use App\Models\BankIntegration;
use App\Models\BankTransaction;
use App\Models\ExpenseCategory;
use App\Utils\Traits\MakesHash;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Session;
@ -232,6 +233,42 @@ class ExpenseApiTest extends TestCase
$this->assertTrue($arr['data'][0]['is_deleted']);
}
public function testExpenseBulkCategorize()
{
$e = Expense::factory()->create([
'company_id' => $this->company->id,
'user_id' => $this->user->id,
]);
$ec = ExpenseCategory::factory()->create([
'company_id' => $this->company->id,
'user_id' => $this->user->id,
'name' => 'Test Category',
]);
nlog("expense category id = {$ec->hashed_id}");
$data = [
'category_id' => $ec->hashed_id,
'action' => 'bulk_categorize',
'ids' => [$this->encodePrimaryKey($e->id)],
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/expenses/bulk', $data);
$arr = $response->json();
nlog($arr);
$this->assertEquals($ec->hashed_id, $arr['data'][0]['category_id']);
}
public function testAddingExpense()
{
$data = [