mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-24 02:14:21 -04:00
expense categories
This commit is contained in:
parent
57faf6eeb5
commit
05caec8aef
435
app/Http/Controllers/ExpenseCategoryController.php
Normal file
435
app/Http/Controllers/ExpenseCategoryController.php
Normal file
@ -0,0 +1,435 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Factory\ExpenseCategoryFactory;
|
||||
use App\Http\Requests\ExpenseCategory\CreateExpenseCategoryRequest;
|
||||
use App\Http\Requests\ExpenseCategory\DestroyExpenseCategoryRequest;
|
||||
use App\Http\Requests\ExpenseCategory\EditExpenseCategoryRequest;
|
||||
use App\Http\Requests\ExpenseCategory\ShowExpenseCategoryRequest;
|
||||
use App\Http\Requests\ExpenseCategory\StoreExpenseCategoryRequest;
|
||||
use App\Http\Requests\ExpenseCategory\UpdateExpenseCategoryRequest;
|
||||
use App\Models\ExpenseCategory;
|
||||
use App\Repositories\BaseRepository;
|
||||
use App\Transformers\ExpenseCategoryTransformer;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/**
|
||||
* Class ExpenseCategoryController.
|
||||
*/
|
||||
class ExpenseCategoryController extends BaseController
|
||||
{
|
||||
use MakesHash;
|
||||
|
||||
protected $entity_type = ExpenseCategory::class;
|
||||
|
||||
protected $entity_transformer = ExpenseCategoryTransformer::class;
|
||||
|
||||
protected $base_repo;
|
||||
|
||||
public function __construct(BaseRepository $base_repo)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->base_repo = $base_repo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Get(
|
||||
* path="/api/v1/expense_categories",
|
||||
* operationId="getExpenseCategorys",
|
||||
* tags={"expense_categories"},
|
||||
* summary="Gets a list of expense_categories",
|
||||
* description="Lists tax rates",
|
||||
* @OA\Parameter(ref="#/components/parameters/index"),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="A list of expense_categories",
|
||||
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
|
||||
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||
* @OA\JsonContent(ref="#/components/schemas/ExpenseCategory"),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=422,
|
||||
* description="Validation error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response="default",
|
||||
* description="Unexpected Error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||
* ),
|
||||
* )
|
||||
*
|
||||
*
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$expense_categories = ExpenseCategory::scope();
|
||||
|
||||
return $this->listResponse($expense_categories);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*
|
||||
*
|
||||
*
|
||||
* @OA\Get(
|
||||
* path="/api/v1/expense_categories/create",
|
||||
* operationId="getExpenseCategoryCreate",
|
||||
* tags={"expense_categories"},
|
||||
* summary="Gets a new blank Expens Category object",
|
||||
* description="Returns a blank object with default values",
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="A blank Expens Category object",
|
||||
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
|
||||
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||
* @OA\JsonContent(ref="#/components/schemas/ExpenseCategory"),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=422,
|
||||
* description="Validation error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||
*
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response="default",
|
||||
* description="Unexpected Error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||
* ),
|
||||
* )
|
||||
*/
|
||||
public function create(CreateExpenseCategoryRequest $request)
|
||||
{
|
||||
$tax_rate = ExpenseCategoryFactory::create(auth()->user()->company()->id, auth()->user()->id);
|
||||
|
||||
return $this->itemResponse($tax_rate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(StoreExpenseCategoryRequest $request)
|
||||
{
|
||||
$tax_rate = ExpenseCategoryFactory::create(auth()->user()->company()->id, auth()->user()->id);
|
||||
$tax_rate->fill($request->all());
|
||||
$tax_rate->save();
|
||||
|
||||
return $this->itemResponse($tax_rate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*
|
||||
*
|
||||
* @OA\Get(
|
||||
* path="/api/v1/expense_categories/{id}",
|
||||
* operationId="showExpenseCategory",
|
||||
* tags={"expense_categories"},
|
||||
* summary="Shows a Expens Category",
|
||||
* description="Displays an ExpenseCategory by id",
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||
* @OA\Parameter(
|
||||
* name="id",
|
||||
* in="path",
|
||||
* description="The ExpenseCategory Hashed ID",
|
||||
* example="D2J234DFA",
|
||||
* required=true,
|
||||
* @OA\Schema(
|
||||
* type="string",
|
||||
* format="string",
|
||||
* ),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="Returns the Expens Category object",
|
||||
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
|
||||
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||
* @OA\JsonContent(ref="#/components/schemas/ExpenseCategory"),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=422,
|
||||
* description="Validation error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||
*
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response="default",
|
||||
* description="Unexpected Error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||
* ),
|
||||
* )
|
||||
*/
|
||||
public function show(ShowExpenseCategoryRequest $request, ExpenseCategory $tax_rate)
|
||||
{
|
||||
return $this->itemResponse($tax_rate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*
|
||||
*
|
||||
* @OA\Get(
|
||||
* path="/api/v1/expense_categories/{id}/edit",
|
||||
* operationId="editExpenseCategory",
|
||||
* tags={"expense_categories"},
|
||||
* summary="Shows a Expens Category for editting",
|
||||
* description="Displays a Expens Category by id",
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||
* @OA\Parameter(
|
||||
* name="id",
|
||||
* in="path",
|
||||
* description="The ExpenseCategory Hashed ID",
|
||||
* example="D2J234DFA",
|
||||
* required=true,
|
||||
* @OA\Schema(
|
||||
* type="string",
|
||||
* format="string",
|
||||
* ),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="Returns the Expens Category object",
|
||||
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
|
||||
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||
* @OA\JsonContent(ref="#/components/schemas/ExpenseCategory"),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=422,
|
||||
* description="Validation error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||
*
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response="default",
|
||||
* description="Unexpected Error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||
* ),
|
||||
* )
|
||||
*/
|
||||
public function edit(EditExpenseCategoryRequest $request, ExpenseCategory $tax_rate)
|
||||
{
|
||||
return $this->itemResponse($tax_rate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param App\Models\Client $client
|
||||
* @return \Illuminate\Http\Response
|
||||
*
|
||||
*
|
||||
*
|
||||
* @OA\Put(
|
||||
* path="/api/v1/expense_categories/{id}",
|
||||
* operationId="updateExpenseCategory",
|
||||
* tags={"expense_categories"},
|
||||
* summary="Updates a tax rate",
|
||||
* description="Handles the updating of a tax rate by id",
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||
* @OA\Parameter(
|
||||
* name="id",
|
||||
* in="path",
|
||||
* description="The ExpenseCategory Hashed ID",
|
||||
* example="D2J234DFA",
|
||||
* required=true,
|
||||
* @OA\Schema(
|
||||
* type="string",
|
||||
* format="string",
|
||||
* ),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="Returns the ExpenseCategory object",
|
||||
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
|
||||
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||
* @OA\JsonContent(ref="#/components/schemas/ExpenseCategory"),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=422,
|
||||
* description="Validation error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||
*
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response="default",
|
||||
* description="Unexpected Error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||
* ),
|
||||
* )
|
||||
*/
|
||||
public function update(UpdateExpenseCategoryRequest $request, ExpenseCategory $tax_rate)
|
||||
{
|
||||
$tax_rate->fill($request->all());
|
||||
$tax_rate->save();
|
||||
|
||||
return $this->itemResponse($tax_rate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*
|
||||
*
|
||||
* @OA\Delete(
|
||||
* path="/api/v1/expense_categories/{id}",
|
||||
* operationId="deleteExpenseCategory",
|
||||
* tags={"expense_categories"},
|
||||
* summary="Deletes a ExpenseCategory",
|
||||
* description="Handles the deletion of an ExpenseCategory by id",
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||
* @OA\Parameter(
|
||||
* name="id",
|
||||
* in="path",
|
||||
* description="The ExpenseCategory Hashed ID",
|
||||
* example="D2J234DFA",
|
||||
* required=true,
|
||||
* @OA\Schema(
|
||||
* type="string",
|
||||
* format="string",
|
||||
* ),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="Returns a HTTP status",
|
||||
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
|
||||
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=422,
|
||||
* description="Validation error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||
*
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response="default",
|
||||
* description="Unexpected Error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||
* ),
|
||||
* )
|
||||
*/
|
||||
public function destroy(DestroyExpenseCategoryRequest $request, ExpenseCategory $tax_rate)
|
||||
{
|
||||
$tax_rate->is_deleted = true;
|
||||
$tax_rate->save();
|
||||
$tax_rate->delete();
|
||||
|
||||
return $this->itemResponse($tax_rate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform bulk actions on the list view.
|
||||
*
|
||||
* @param BulkExpenseCategoryRequest $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*
|
||||
*
|
||||
* @OA\Post(
|
||||
* path="/api/v1/expense_categories/bulk",
|
||||
* operationId="bulkExpenseCategorys",
|
||||
* tags={"expense_categories"},
|
||||
* summary="Performs bulk actions on an array of ExpenseCategorys",
|
||||
* description="",
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||
* @OA\Parameter(ref="#/components/parameters/index"),
|
||||
* @OA\RequestBody(
|
||||
* description="Expens Categorys",
|
||||
* required=true,
|
||||
* @OA\MediaType(
|
||||
* mediaType="application/json",
|
||||
* @OA\Schema(
|
||||
* type="array",
|
||||
* @OA\Items(
|
||||
* type="integer",
|
||||
* description="Array of hashed IDs to be bulk 'actioned",
|
||||
* example="[0,1,2,3]",
|
||||
* ),
|
||||
* )
|
||||
* )
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="The ExpenseCategory List response",
|
||||
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
|
||||
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||
* @OA\JsonContent(ref="#/components/schemas/Webhook"),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=422,
|
||||
* description="Validation error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response="default",
|
||||
* description="Unexpected Error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||
* ),
|
||||
* )
|
||||
*/
|
||||
public function bulk()
|
||||
{
|
||||
$action = request()->input('action');
|
||||
|
||||
$ids = request()->input('ids');
|
||||
|
||||
$expense_categories = ExpenseCategory::withTrashed()->find($this->transformKeys($ids));
|
||||
|
||||
$expense_categories->each(function ($tax_rate, $key) use ($action) {
|
||||
if (auth()->user()->can('edit', $tax_rate)) {
|
||||
$this->base_repo->{$action}($tax_rate);
|
||||
}
|
||||
});
|
||||
|
||||
return $this->listResponse(ExpenseCategory::withTrashed()->whereIn('id', $this->transformKeys($ids)));
|
||||
}
|
||||
}
|
13
app/Http/Controllers/OpenAPI/ExpenseCategorySchema.php
Normal file
13
app/Http/Controllers/OpenAPI/ExpenseCategorySchema.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
/**
|
||||
* @OA\Schema(
|
||||
* schema="ExpenseCategory",
|
||||
* type="object",
|
||||
* @OA\Property(property="id", type="string", example="Opnel5aKBz", description="______"),
|
||||
* @OA\Property(property="name", type="string", example="Accounting", description="______"),
|
||||
* @OA\Property(property="user_id", type="string", example="XS987sD", description="______"),
|
||||
* @OA\Property(property="is_deleted", type="boolean", example=true, description="______"),
|
||||
* @OA\Property(property="updated_at", type="string", example="2", description="______"),
|
||||
* @OA\Property(property="created_at", type="string", example="2", description="______"),
|
||||
* )
|
||||
*/
|
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\ExpenseCategory;
|
||||
|
||||
use App\Models\ExpenseCategory;
|
||||
use App\Utils\Traits\BulkOptions;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class BulkExpenseCategoryRequest extends FormRequest
|
||||
{
|
||||
use BulkOptions;
|
||||
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth()->user()->->isAdmin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Http\Requests\ExpenseCategory;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Models\ExpenseCategory;
|
||||
|
||||
class CreateExpenseCategoryRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize() : bool
|
||||
{
|
||||
return auth()->user()->can('create', ExpenseCategory::class);
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Http\Requests\ExpenseCategory;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Models\ExpenseCategory;
|
||||
|
||||
class DestroyExpenseCategoryRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize() : bool
|
||||
{
|
||||
return auth()->user()->can('edit', $this->expense_category);
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Http\Requests\ExpenseCategory;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Models\ExpenseCategory;
|
||||
|
||||
class EditExpenseCategoryRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize() : bool
|
||||
{
|
||||
return auth()->user()->can('edit', $this->expense_category);
|
||||
}
|
||||
|
||||
// public function prepareForValidation()
|
||||
// {
|
||||
// $input = $this->all();
|
||||
|
||||
// //$input['id'] = $this->encodePrimaryKey($input['id']);
|
||||
|
||||
// $this->replace($input);
|
||||
|
||||
// }
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Http\Requests\ExpenseCategory;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Models\ExpenseCategory;
|
||||
|
||||
class ShowExpenseCategoryRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize() : bool
|
||||
{
|
||||
return auth()->user()->can('view', $this->expense_category);
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Http\Requests\ExpenseCategory;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Http\ValidationRules\ExpenseCategory\UniqueExpenseCategoryNumberRule;
|
||||
use App\Http\ValidationRules\ValidExpenseCategoryGroupSettingsRule;
|
||||
use App\Models\ExpenseCategory;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class StoreExpenseCategoryRequest extends Request
|
||||
{
|
||||
use MakesHash;
|
||||
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize() : bool
|
||||
{
|
||||
return auth()->user()->can('create', ExpenseCategory::class);
|
||||
}
|
||||
|
||||
public function rules()
|
||||
{
|
||||
$rules = [];
|
||||
$rules['name'] = 'unique:expense_categories,name,'.$this->id.',id,company_id,'.$this->company_id;;
|
||||
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
protected function prepareForValidation()
|
||||
{
|
||||
// $input = $this->all();
|
||||
|
||||
|
||||
// $this->replace($input);
|
||||
}
|
||||
|
||||
// public function messages()
|
||||
// {
|
||||
// return [
|
||||
// 'unique' => ctrans('validation.unique', ['attribute' => 'email']),
|
||||
// //'required' => trans('validation.required', ['attribute' => 'email']),
|
||||
// 'contacts.*.email.required' => ctrans('validation.email', ['attribute' => 'email']),
|
||||
// ];
|
||||
// }
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Http\Requests\ExpenseCategory;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Http\ValidationRules\IsDeletedRule;
|
||||
use App\Utils\Traits\ChecksEntityStatus;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class UpdateExpenseCategoryRequest extends Request
|
||||
{
|
||||
use MakesHash;
|
||||
use ChecksEntityStatus;
|
||||
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize() : bool
|
||||
{
|
||||
return auth()->user()->can('edit', $this->expense_category);
|
||||
}
|
||||
|
||||
public function rules()
|
||||
{
|
||||
/* Ensure we have a client name, and that all emails are unique*/
|
||||
$rules = [];
|
||||
|
||||
if ($this->input('number')) {
|
||||
$rules['name'] = 'unique:expense_categories,name,'.$this->id.',id,company_id,'.$this->expense_category->name;
|
||||
}
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
// public function messages()
|
||||
// {
|
||||
// return [
|
||||
// 'unique' => ctrans('validation.unique', ['attribute' => 'email']),
|
||||
// 'email' => ctrans('validation.email', ['attribute' => 'email']),
|
||||
// 'name.required' => ctrans('validation.required', ['attribute' => 'name']),
|
||||
// 'required' => ctrans('validation.required', ['attribute' => 'email']),
|
||||
// ];
|
||||
// }
|
||||
|
||||
protected function prepareForValidation()
|
||||
{
|
||||
$input = $this->all();
|
||||
|
||||
$this->replace($input);
|
||||
}
|
||||
}
|
32
app/Policies/ExpenseCategoryPolicy.php
Normal file
32
app/Policies/ExpenseCategoryPolicy.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\Expense;
|
||||
use App\Models\User;
|
||||
|
||||
/**
|
||||
* Class ExpensePolicy.
|
||||
*/
|
||||
class ExpenseCategoryPolicy extends EntityPolicy
|
||||
{
|
||||
/**
|
||||
* Checks if the user has create permissions.
|
||||
*
|
||||
* @param User $user
|
||||
* @return bool
|
||||
*/
|
||||
public function create(User $user) : bool
|
||||
{
|
||||
return $user->isAdmin() || $user->hasPermission('create_expense_categories') || $user->hasPermission('create_all');
|
||||
}
|
||||
}
|
@ -20,6 +20,7 @@ use App\Models\Credit;
|
||||
use App\Models\Design;
|
||||
use App\Models\Document;
|
||||
use App\Models\Expense;
|
||||
use App\Models\ExpenseCategory;
|
||||
use App\Models\GroupSetting;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Payment;
|
||||
@ -42,6 +43,7 @@ use App\Policies\CompanyTokenPolicy;
|
||||
use App\Policies\CreditPolicy;
|
||||
use App\Policies\DesignPolicy;
|
||||
use App\Policies\DocumentPolicy;
|
||||
use App\Policies\ExpenseCategoryPolicy;
|
||||
use App\Policies\ExpensePolicy;
|
||||
use App\Policies\GroupSettingPolicy;
|
||||
use App\Policies\InvoicePolicy;
|
||||
@ -78,6 +80,7 @@ class AuthServiceProvider extends ServiceProvider
|
||||
Design::class => DesignPolicy::class,
|
||||
Document::class => DocumentPolicy::class,
|
||||
Expense::class => ExpensePolicy::class,
|
||||
ExpenseCategory::class => ExpenseCategoryPolicy::class,
|
||||
GroupSetting::class => GroupSettingPolicy::class,
|
||||
Invoice::class => InvoicePolicy::class,
|
||||
Payment::class => PaymentPolicy::class,
|
||||
|
@ -58,7 +58,7 @@ class ExpenseTransformer extends EntityTransformer
|
||||
'bank_id' => (string) $expense->bank_id ?: '',
|
||||
'invoice_currency_id' => (string) $expense->invoice_currency_id ?: '',
|
||||
'expense_currency_id' => (string) $expense->expense_currency_id ?: '',
|
||||
'invoice_category_id' => (string) $expense->invoice_category_id ?: '',
|
||||
'category_id' => (string) $expense->category_id ?: '',
|
||||
'payment_type_id' => (string) $expense->payment_type_id ?: '',
|
||||
'recurring_expense_id' => (string) $expense->recurring_expense_id ?: '',
|
||||
'is_deleted' => (bool) $expense->is_deleted,
|
||||
|
37
database/factories/ExpenseCategoryFactory.php
Normal file
37
database/factories/ExpenseCategoryFactory.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\ExpenseCategory;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class ExpenseCategoryFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* The name of the factory's corresponding model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $model = ExpenseCategory::class;
|
||||
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function definition()
|
||||
{
|
||||
return [
|
||||
'name' => $this->faker->text(10),
|
||||
];
|
||||
}
|
||||
}
|
@ -1244,11 +1244,12 @@ class CreateUsersTable extends Migration
|
||||
$table->increments('id');
|
||||
$table->unsignedInteger('user_id');
|
||||
$table->unsignedInteger('company_id')->index();
|
||||
$table->string('name')->nullable();
|
||||
$table->timestamps(6);
|
||||
$table->softDeletes();
|
||||
$table->string('name')->nullable();
|
||||
|
||||
$table->index(['company_id', 'deleted_at']);
|
||||
$table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade')->onUpdate('cascade');
|
||||
});
|
||||
|
||||
Schema::create('expenses', function (Blueprint $table) {
|
||||
|
@ -16,6 +16,10 @@ class ProjectNumberColumn extends Migration
|
||||
Schema::table('projects', function($table){
|
||||
$table->string('number')->nullable();
|
||||
});
|
||||
|
||||
Schema::table('expenses', function ($t){
|
||||
$t->renameColumn('expense_date', 'date');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -69,6 +69,10 @@ Route::group(['middleware' => ['api_db', 'token_auth', 'locale'], 'prefix' => 'a
|
||||
|
||||
Route::post('expenses/bulk', 'ExpenseController@bulk')->name('expenses.bulk');
|
||||
|
||||
Route::resource('expense_categories', 'ExpenseCategoryController'); // name = (expense_categories. index / create / show / update / destroy / edit
|
||||
|
||||
Route::post('expense_categories/bulk', 'ExpenseCategoryController@bulk')->name('expense_categories.bulk');
|
||||
|
||||
Route::resource('tasks', 'TaskController'); // name = (tasks. index / create / show / update / destroy / edit
|
||||
|
||||
Route::post('tasks/bulk', 'TaskController@bulk')->name('tasks.bulk');
|
||||
|
152
tests/Feature/ExpenseCategoryApiTest.php
Normal file
152
tests/Feature/ExpenseCategoryApiTest.php
Normal file
@ -0,0 +1,152 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\DataMapper\DefaultSettings;
|
||||
use App\Models\Account;
|
||||
use App\Models\ExpenseCategory;
|
||||
use App\Models\ExpenseCategoryContact;
|
||||
use App\Models\Company;
|
||||
use App\Models\User;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Faker\Factory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Foundation\Testing\WithFaker;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Tests\MockAccountData;
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @covers App\Http\Controllers\ExpenseCategoryController
|
||||
*/
|
||||
class ExpenseCategoryApiTest extends TestCase
|
||||
{
|
||||
use MakesHash;
|
||||
use DatabaseTransactions;
|
||||
use MockAccountData;
|
||||
|
||||
public function setUp() :void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->makeTestData();
|
||||
|
||||
Session::start();
|
||||
|
||||
$this->faker = \Faker\Factory::create();
|
||||
|
||||
Model::reguard();
|
||||
}
|
||||
|
||||
public function testExpenseCategoryPost()
|
||||
{
|
||||
$data = [
|
||||
'public_notes' => $this->faker->firstName,
|
||||
];
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->post('/api/v1/expense_categories', $data);
|
||||
|
||||
$response->assertStatus(200);
|
||||
}
|
||||
|
||||
public function testExpenseCategoryPut()
|
||||
{
|
||||
$data = [
|
||||
'public_notes' => $this->faker->firstName,
|
||||
'id_number' => 'Coolio',
|
||||
];
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->put('/api/v1/expense_categories/'.$this->encodePrimaryKey($this->expense_category->id), $data);
|
||||
|
||||
$response->assertStatus(200);
|
||||
}
|
||||
|
||||
public function testExpenseCategoryGet()
|
||||
{
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->get('/api/v1/expense_categories/'.$this->encodePrimaryKey($this->expense_category->id));
|
||||
|
||||
$response->assertStatus(200);
|
||||
}
|
||||
|
||||
public function testExpenseCategoryNotArchived()
|
||||
{
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->get('/api/v1/expense_categories/'.$this->encodePrimaryKey($this->expense_category->id));
|
||||
|
||||
$arr = $response->json();
|
||||
|
||||
$this->assertEquals(0, $arr['data']['archived_at']);
|
||||
}
|
||||
|
||||
public function testExpenseCategoryArchived()
|
||||
{
|
||||
$data = [
|
||||
'ids' => [$this->encodePrimaryKey($this->expense_category->id)],
|
||||
];
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->post('/api/v1/expense_categories/bulk?action=archive', $data);
|
||||
|
||||
$arr = $response->json();
|
||||
|
||||
$this->assertNotNull($arr['data'][0]['archived_at']);
|
||||
}
|
||||
|
||||
public function testExpenseCategoryRestored()
|
||||
{
|
||||
$data = [
|
||||
'ids' => [$this->encodePrimaryKey($this->expense_category->id)],
|
||||
];
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->post('/api/v1/expense_categories/bulk?action=restore', $data);
|
||||
|
||||
$arr = $response->json();
|
||||
|
||||
$this->assertEquals(0, $arr['data'][0]['archived_at']);
|
||||
}
|
||||
|
||||
public function testExpenseCategoryDeleted()
|
||||
{
|
||||
$data = [
|
||||
'ids' => [$this->encodePrimaryKey($this->expense_category->id)],
|
||||
];
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->post('/api/v1/expense_categories/bulk?action=delete', $data);
|
||||
|
||||
$arr = $response->json();
|
||||
|
||||
$this->assertTrue($arr['data'][0]['is_deleted']);
|
||||
}
|
||||
}
|
@ -32,6 +32,7 @@ use App\Models\CompanyGateway;
|
||||
use App\Models\CompanyToken;
|
||||
use App\Models\Credit;
|
||||
use App\Models\Expense;
|
||||
use App\Models\ExpenseCategory;
|
||||
use App\Models\GroupSetting;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\InvoiceInvitation;
|
||||
@ -80,6 +81,8 @@ trait MockAccountData
|
||||
|
||||
public $task;
|
||||
|
||||
public $expense_category;
|
||||
|
||||
public function makeTestData()
|
||||
{
|
||||
|
||||
@ -225,6 +228,11 @@ trait MockAccountData
|
||||
'company_id' => $this->company->id,
|
||||
]);
|
||||
|
||||
$this->expense_category = ExpenseCategory::factory()->create([
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $this->company->id,
|
||||
]);
|
||||
|
||||
$gs = new GroupSetting;
|
||||
$gs->name = 'Test';
|
||||
$gs->company_id = $this->client->company_id;
|
||||
|
Loading…
x
Reference in New Issue
Block a user