expense categories

This commit is contained in:
David Bomba 2020-10-13 15:08:56 +11:00
parent 57faf6eeb5
commit 05caec8aef
18 changed files with 970 additions and 2 deletions

View 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)));
}
}

View 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="______"),
* )
*/

View File

@ -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 [];
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
// }
}

View File

@ -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);
}
}

View File

@ -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']),
// ];
// }
}

View File

@ -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);
}
}

View 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');
}
}

View File

@ -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,

View File

@ -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,

View 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),
];
}
}

View File

@ -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) {

View File

@ -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');
});
}
/**

View File

@ -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');

View 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']);
}
}

View File

@ -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;