Compare commits

..

14 Commits

Author SHA1 Message Date
Husnu Setiawan 3fda04a881 fix bug auth login fail
WMS API/ERP-API/pipeline/head This commit looks good Details
2025-02-14 17:57:29 +07:00
Husnu Setiawan c445ee43e3 update account 2025-02-13 22:42:17 +07:00
Husnu Setiawan ed7182f9fd fix bug forget permission
WMS API/ERP-API/pipeline/head This commit looks good Details
2025-02-12 18:41:06 +07:00
Husnu Setiawan 346bc8513e forget cache permission when update role
WMS API/ERP-API/pipeline/head This commit looks good Details
2025-02-12 17:29:22 +07:00
Husnu Setiawan 43937cbb04 add api crud account
WMS API/ERP-API/pipeline/head This commit looks good Details
2025-02-12 15:29:39 +07:00
Husnu Setiawan 6e5f30df4d fix bug role delete
WMS API/ERP-API/pipeline/head This commit looks good Details
2025-02-11 17:07:14 +07:00
Husnu Setiawan 4ce31cd7ae fix bug api role
WMS API/ERP-API/pipeline/head This commit looks good Details
2025-02-11 16:58:19 +07:00
Husnu Setiawan 4da22a3fcd fix bug sort permission
WMS API/ERP-API/pipeline/head This commit looks good Details
2025-02-11 16:15:52 +07:00
Husnu Setiawan c070e0dc38 add list permission
WMS API/ERP-API/pipeline/head This commit looks good Details
2025-02-11 16:05:49 +07:00
Husnu Setiawan 459a22127e add role and permissions
WMS API/ERP-API/pipeline/head This commit looks good Details
2025-02-11 12:55:04 +07:00
Husnu Setiawan d24474f4e1 envoy fix (2)
WMS API/ERP-API/pipeline/head This commit looks good Details
2025-02-11 12:10:01 +07:00
Husnu Setiawan b864838631 envoy fix
WMS API/ERP-API/pipeline/head There was a failure building this commit Details
2025-02-11 12:08:03 +07:00
Husnu Setiawan 5644946ed8 require envoy
WMS API/ERP-API/pipeline/head There was a failure building this commit Details
2025-02-11 11:56:45 +07:00
Husnu Setiawan 3ad3a4d00f user and role
WMS API/ERP-API/pipeline/head There was a failure building this commit Details
2025-02-11 11:14:39 +07:00
72 changed files with 2544 additions and 18 deletions

81
Envoy.blade.php Normal file
View File

@ -0,0 +1,81 @@
@servers(['prod' => 'ubuntu@172.26.12.217', 'dev' => 'ubuntu@smgdev.top'])
@setup
$repository = 'git@172.26.1.255:SMG_DEV/ERP-API.git';
$releases_dir = '/var/www/erp-api/releases';
$app_dir = '/var/www/erp-api';
$release = date('YmdHis');
$new_release_dir = $releases_dir .'/'. $release;
@endsetup
@task('clone_repository_dev')
echo 'Cloning repository'
[ -d {{ $releases_dir }} ] || mkdir {{ $releases_dir }}
git clone --depth 1 --single-branch --branch development {{ $repository }} {{ $new_release_dir }}
cd {{ $new_release_dir }}
@endtask
@task('clone_repository_prod')
echo 'Cloning repository'
[ -d {{ $releases_dir }} ] || mkdir {{ $releases_dir }}
git clone --depth 1 --single-branch --branch production {{ $repository }} {{ $new_release_dir }}
cd {{ $new_release_dir }}
@endtask
@task('run_composer')
echo "Starting deployment ({{ $release }})"
cd {{ $new_release_dir }}
composer install --prefer-dist --no-scripts -q -o
@endtask
@task('update_symlinks')
echo "Linking storage directory"
rm -rf {{ $new_release_dir }}/storage
ln -nfs {{ $app_dir }}/storage {{ $new_release_dir }}/storage
echo 'Linking .env file'
ln -nfs {{ $app_dir }}/.env {{ $new_release_dir }}/.env
echo 'Linking current release'
ln -nfs {{ $new_release_dir }} {{ $app_dir }}/current
@endtask
@task('setup_laravel')
cd {{ $app_dir }}/current
php artisan migrate --force
php artisan storage:link
php artisan db:seed --class PermissionSeeder --force
@endtask
@task('clean_old_releases')
# This lists our releases by modification time and delete all but the 3 most recent.
purging=$(ls -dt {{ $releases_dir }}/* | tail -n +5);
if [ "{{ $releases_dir }}" != "" ]; then
if [ "$purging" != "" ]; then
echo Purging old releases: $purging;
rm -rf $purging;
else
echo "No releases found for purging at this time";
fi
fi
@endtask
@story('deploy',["on" => "prod"])
clone_repository_prod
run_composer
update_symlinks
setup_laravel
clean_old_releases
@endstory
@story('deploy-dev',["on" => "dev"])
clone_repository_dev
run_composer
update_symlinks
setup_laravel
clean_old_releases
@endstory

29
Jenkinsfile vendored Normal file
View File

@ -0,0 +1,29 @@
pipeline {
agent any
stages
{
stage("Deploy Dev"){
when {
branch 'development'
}
steps {
sshagent(credentials: ['dev-id_rsa']) {
sh "composer install"
sh "./vendor/bin/envoy run deploy-dev"
}
}
}
stage("Deploy Prod"){
when {
branch 'production'
}
steps {
sshagent(credentials: ['dev-id_rsa']) {
sh "composer install"
sh "./vendor/bin/envoy run deploy"
}
}
}
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace App\Http\Controllers\Accounting\Account;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Requests\Accounting\Account\DeleteRequest;
use App\Http\Resources\Accounting\Account\ListResource as RowResource;
use App\Repositories\Accounting\AccountRepository;
use App\Models\Account;
class DeleteController extends Controller
{
/**
* Handle the incoming request.
*/
public function __invoke(DeleteRequest $request, Account $account, AccountRepository $repository)
{
$data = $repository->delete($account);
return response()->json([
"success" => true
]);
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace App\Http\Controllers\Accounting\Account;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Requests\Accounting\Account\ListRequest;
use App\Http\Resources\Accounting\Account\ListResource;
use App\Repositories\Accounting\AccountRepository;
class ListController extends Controller
{
/**
* Handle the incoming request.
*/
public function __invoke(ListRequest $request, AccountRepository $repository)
{
$params = $request->validated();
$data = $repository->list($params);
return ListResource::collection($data);
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace App\Http\Controllers\Accounting\Account;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Requests\Accounting\Account\StoreRequest;
use App\Http\Resources\Accounting\Account\ListResource as RowResource;
use App\Repositories\Accounting\AccountRepository;
class StoreController extends Controller
{
/**
* Handle the incoming request.
*/
public function __invoke(StoreRequest $request, AccountRepository $repository)
{
$params = $request->validated();
$data = $repository->create($params);
return RowResource::make($data);
}
}

View File

@ -0,0 +1,23 @@
<?php
namespace App\Http\Controllers\Accounting\Account;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Requests\Accounting\Account\UpdateRequest;
use App\Http\Resources\Accounting\Account\ListResource as RowResource;
use App\Repositories\Accounting\AccountRepository;
use App\Models\Account;
class UpdateController extends Controller
{
/**
* Handle the incoming request.
*/
public function __invoke(UpdateRequest $request, Account $account, AccountRepository $repository)
{
$params = $request->validated();
$data = $repository->update($account, $params);
return RowResource::make($data);
}
}

View File

@ -6,6 +6,7 @@ use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Requests\Auth\LoginRequest;
use App\Repositories\Auth\AuthRepository;
use App\Http\Resources\Auth\CurrentResource;
class LoginController extends Controller
{
@ -18,7 +19,8 @@ class LoginController extends Controller
$data = $authRepository->login($params);
return [
"success" => true,
"data" => $data
"user" => CurrentResource::make($data[0]),
"token" => $data[1]
];
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace App\Http\Controllers\Auth\Permission;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Requests\Auth\Permission\ListRequest;
use App\Http\Resources\Auth\Permission\ListResource;
use App\Repositories\Auth\PermissionRepository;
class ListController extends Controller
{
/**
* Handle the incoming request.
*/
public function __invoke(ListRequest $request, PermissionRepository $repository)
{
$params = $request->validated();
$data = $repository->list($params);
return ListResource::collection($data);
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace App\Http\Controllers\Auth\Role;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Requests\Auth\Role\DeleteRequest;
use App\Http\Resources\Auth\Role\ListResource as RowResource;
use App\Repositories\Auth\RoleRepository;
use App\Models\Role;
class DeleteController extends Controller
{
/**
* Handle the incoming request.
*/
public function __invoke(DeleteRequest $request, Role $role, RoleRepository $repository)
{
$data = $repository->delete($role);
return response()->json([
"success" => true
]);
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace App\Http\Controllers\Auth\Role;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Requests\Auth\Role\ListRequest;
use App\Http\Resources\Auth\Role\ListResource;
use App\Repositories\Auth\RoleRepository;
class ListController extends Controller
{
/**
* Handle the incoming request.
*/
public function __invoke(ListRequest $request, RoleRepository $repository)
{
$params = $request->validated();
$data = $repository->list($params);
return ListResource::collection($data);
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace App\Http\Controllers\Auth\Role;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Requests\Auth\Role\StoreRequest;
use App\Http\Resources\Auth\Role\ListResource as RowResource;
use App\Repositories\Auth\RoleRepository;
class StoreController extends Controller
{
/**
* Handle the incoming request.
*/
public function __invoke(StoreRequest $request, RoleRepository $repository)
{
$params = $request->validated();
$data = $repository->create($params);
return RowResource::make($data);
}
}

View File

@ -0,0 +1,23 @@
<?php
namespace App\Http\Controllers\Auth\Role;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Requests\Auth\Role\UpdateRequest;
use App\Http\Resources\Auth\Role\ListResource as RowResource;
use App\Repositories\Auth\RoleRepository;
use App\Models\Role;
class UpdateController extends Controller
{
/**
* Handle the incoming request.
*/
public function __invoke(UpdateRequest $request, Role $role, RoleRepository $repository)
{
$params = $request->validated();
$data = $repository->update($role, $params);
return RowResource::make($data);
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace App\Http\Controllers\Auth\User;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Requests\Auth\User\DeleteRequest;
use App\Http\Resources\Auth\User\ListResource as RowResource;
use App\Repositories\Auth\UserRepository;
use App\Models\User;
class DeleteController extends Controller
{
/**
* Handle the incoming request.
*/
public function __invoke(DeleteRequest $request, User $user, UserRepository $repository)
{
$data = $repository->delete($user);
return response()->json([
"success" => true
]);
}
}

View File

@ -4,14 +4,19 @@ namespace App\Http\Controllers\Auth\User;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Requests\Auth\User\ListRequest;
use App\Http\Resources\Auth\User\ListResource;
use App\Repositories\Auth\UserRepository;
class ListController extends Controller
{
/**
* Handle the incoming request.
*/
public function __invoke(Request $request)
public function __invoke(ListRequest $request, UserRepository $repository)
{
//
$params = $request->validated();
$data = $repository->list($params);
return ListResource::collection($data);
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace App\Http\Controllers\Auth\User;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Requests\Auth\User\StoreRequest;
use App\Http\Resources\Auth\User\ListResource as RowResource;
use App\Repositories\Auth\UserRepository;
class StoreController extends Controller
{
/**
* Handle the incoming request.
*/
public function __invoke(StoreRequest $request, UserRepository $repository)
{
$params = $request->validated();
$data = $repository->create($params);
return RowResource::make($data);
}
}

View File

@ -0,0 +1,23 @@
<?php
namespace App\Http\Controllers\Auth\User;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Requests\Auth\User\UpdateRequest;
use App\Http\Resources\Auth\User\ListResource as RowResource;
use App\Repositories\Auth\UserRepository;
use App\Models\User;
class UpdateController extends Controller
{
/**
* Handle the incoming request.
*/
public function __invoke(UpdateRequest $request, User $user, UserRepository $repository)
{
$params = $request->validated();
$data = $repository->update($user, $params);
return RowResource::make($data);
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace App\Http\Requests\Accounting\Account;
use Illuminate\Foundation\Http\FormRequest;
class DeleteRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return auth()->user()->checkPermission("accounting.account:delete");
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
];
}
}

View File

@ -0,0 +1,39 @@
<?php
namespace App\Http\Requests\Accounting\Account;
use Illuminate\Foundation\Http\FormRequest;
class ListRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return auth()->user()->checkPermission("accounting.account:read");
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'limit' => 'nullable',
'offset' => 'nullable',
'search' => 'nullable',
'filter' => 'nullable|array',
'filter.*.column' => 'required|in:code,name,sheet,type,category,subcategory',
'filter.*.operator' => 'nullable|in:eq,in',
'filter.*.query' => 'required',
'sort' => 'nullable|array',
'sort.column' => 'nullable|in:code,name,sheet,type,category,subcategory',
'sort.dir' => 'nullable',
];
}
}

View File

@ -0,0 +1,35 @@
<?php
namespace App\Http\Requests\Accounting\Account;
use Illuminate\Foundation\Http\FormRequest;
class StoreRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return auth()->user()->checkPermission("accounting.account:create");
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'name' => 'required|string',
'code' => 'required|string|unique:accounts',
'sheet' => 'required|string',
'type' => 'required|string',
'category' => 'required|string',
'subcategory' => 'nullable|string',
'structure' => 'required|string',
'totaling' => 'nullable|string',
];
}
}

View File

@ -0,0 +1,34 @@
<?php
namespace App\Http\Requests\Accounting\Account;
use Illuminate\Foundation\Http\FormRequest;
class UpdateRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return auth()->user()->checkPermission("accounting.account:update");
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'name' => 'required|string',
'code' => 'required|string|unique:accounts,code,'.$this->account->id,
'sheet' => 'required|string',
'type' => 'required|string',
'category' => 'required|string',
'subcategory' => 'nullable|string',
'structure' => 'required|string',
];
}
}

View File

@ -0,0 +1,39 @@
<?php
namespace App\Http\Requests\Auth\Permission;
use Illuminate\Foundation\Http\FormRequest;
class ListRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return auth()->user()->checkPermission("auth.role:read");
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'limit' => 'nullable',
'offset' => 'nullable',
'search' => 'nullable',
'filter' => 'nullable|array',
'filter.*.column' => 'required|in:name,code',
'filter.*.operator' => 'nullable|in:eq,in',
'filter.*.query' => 'required',
'sort' => 'nullable|array',
'sort.column' => 'nullable|in:name,code',
'sort.dir' => 'nullable',
];
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace App\Http\Requests\Auth\Role;
use Illuminate\Foundation\Http\FormRequest;
class DeleteRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return auth()->user()->checkPermission("auth.role:delete");
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
];
}
}

View File

@ -0,0 +1,39 @@
<?php
namespace App\Http\Requests\Auth\Role;
use Illuminate\Foundation\Http\FormRequest;
class ListRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return auth()->user()->checkPermission("auth.role:read");
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'limit' => 'nullable',
'offset' => 'nullable',
'search' => 'nullable',
'filter' => 'nullable|array',
'filter.*.column' => 'required|in:name',
'filter.*.operator' => 'nullable|in:eq,in',
'filter.*.query' => 'required',
'sort' => 'nullable|array',
'sort.column' => 'nullable|in:name',
'sort.dir' => 'nullable',
];
}
}

View File

@ -0,0 +1,30 @@
<?php
namespace App\Http\Requests\Auth\Role;
use Illuminate\Foundation\Http\FormRequest;
class StoreRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return auth()->user()->checkPermission("auth.role:create");
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'name' => 'required|string',
'permissions' => 'nullable|array',
'permissions.*' => 'nullable|integer'
];
}
}

View File

@ -0,0 +1,30 @@
<?php
namespace App\Http\Requests\Auth\Role;
use Illuminate\Foundation\Http\FormRequest;
class UpdateRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return auth()->user()->checkPermission("auth.role:update");
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'name' => 'required|string',
'permissions' => 'nullable|array',
'permissions.*' => 'nullable|integer'
];
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace App\Http\Requests\Auth\User;
use Illuminate\Foundation\Http\FormRequest;
class DeleteRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return auth()->user()->checkPermission("auth.user:delete");
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
];
}
}

View File

@ -11,10 +11,7 @@ class ListRequest extends FormRequest
*/
public function authorize(): bool
{
$user = auth()->user();
$user->load("roles");
return false;
return auth()->user()->checkPermission("auth.user:read");
}
/**
@ -25,7 +22,18 @@ class ListRequest extends FormRequest
public function rules(): array
{
return [
//
'limit' => 'nullable',
'offset' => 'nullable',
'search' => 'nullable',
'filter' => 'nullable|array',
'filter.*.column' => 'required|in:name,email',
'filter.*.operator' => 'nullable|in:eq,in',
'filter.*.query' => 'required',
'sort' => 'nullable|array',
'sort.column' => 'nullable|in:name,email',
'sort.dir' => 'nullable',
];
}
}

View File

@ -0,0 +1,31 @@
<?php
namespace App\Http\Requests\Auth\User;
use Illuminate\Foundation\Http\FormRequest;
class StoreRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return auth()->user()->checkPermission("auth.user:create");
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'name' => 'required|string',
'email' => 'required|string',
'roles' => 'nullable|array',
'roles.*' => 'nullable|integer'
];
}
}

View File

@ -0,0 +1,31 @@
<?php
namespace App\Http\Requests\Auth\User;
use Illuminate\Foundation\Http\FormRequest;
class UpdateRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return auth()->user()->checkPermission("auth.user:update");
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'name' => 'required|string',
'email' => 'required|string',
'roles' => 'nullable|array',
'roles.*' => 'nullable|integer'
];
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace App\Http\Resources\Accounting\Account;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class ListResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
"id" => $this->id,
"name" => $this->name,
"code" => $this->code,
"sheet" => $this->sheet,
"type" => $this->type,
"category" => $this->category,
"subcategory" => $this->subcategory,
"structure" => $this->structure
];
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace App\Http\Resources\Accounting\Account;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class SimpleResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
"id" => $this->id,
"name" => $this->name,
];
}
}

View File

@ -4,6 +4,7 @@ namespace App\Http\Resources\Auth;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
use App\Http\Resources\Auth\Role\SimpleResource as RoleResource;
class CurrentResource extends JsonResource
{
@ -17,7 +18,13 @@ class CurrentResource extends JsonResource
return [
"id" => $this->id,
"name" => $this->name,
"email" => $this->email
"email" => $this->email,
"roles" => RoleResource::collection($this->roles),
"permissions" => $this->roles->flatMap(function($role){
return $role->permissions->map(function($permision){
return $permision->code;
});
})
];
}
}

View File

@ -0,0 +1,23 @@
<?php
namespace App\Http\Resources\Auth\Permission;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class ListResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
"id" => $this->id,
"code" => $this->code,
"name" => $this->name
];
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace App\Http\Resources\Auth\Role;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
use App\Http\Resources\Auth\Permission\ListResource as PermissionResource;
class ListResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
"id" => $this->id,
"name" => $this->name,
"permissions" => PermissionResource::collection($this->permissions)
];
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace App\Http\Resources\Auth\Role;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class SimpleResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
"id" => $this->id,
"name" => $this->name,
];
}
}

View File

@ -0,0 +1,25 @@
<?php
namespace App\Http\Resources\Auth\User;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
use App\Http\Resources\Auth\Role\ListResource as RoleResource;
class ListResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
"id" => $this->id,
"name" => $this->name,
"email" => $this->email,
"roles" => RoleResource::collection($this->roles)
];
}
}

23
app/Models/Account.php Normal file
View File

@ -0,0 +1,23 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Spatie\Activitylog\Traits\LogsActivity;
use Spatie\Activitylog\LogOptions;
class Account extends Model
{
use HasFactory;
use LogsActivity;
protected $fillable = ['code', 'name','sheet','type','category','subcategory','structure','totaling'];
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults();
}
}

View File

@ -5,11 +5,33 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Spatie\Activitylog\Traits\LogsActivity;
use Spatie\Activitylog\LogOptions;
class Role extends Model
{
use HasFactory;
use LogsActivity;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'name',
];
public function permissions(){
return $this->hasMany(Permission::class);
return $this->belongsToMany(Permission::class,"role_permission");
}
public function users(){
return $this->belongsToMany(User::class,'user_role');
}
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults();
}
}

View File

@ -7,10 +7,15 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
use Cache;
use Spatie\Activitylog\Traits\LogsActivity;
use Spatie\Activitylog\LogOptions;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
use LogsActivity;
/**
* The attributes that are mass assignable.
@ -43,7 +48,33 @@ class User extends Authenticatable
'password' => 'hashed',
];
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults();
}
public function roles(){
return $this->hasMany(Role::class)->with("permissions");
return $this->belongsToMany(Role::class,'user_role')->with("permissions");
}
public function forgetPermission(){
Cache::forget("permission_".$this->id);
}
public function getPermission(){
$user = $this;
return Cache::rememberForever("permission_".$this->id, function() use ($user){
return $user->roles->flatMap(function($role){
return $role->permissions->map(function($permission){
return $permission->code;
});
});
});
}
public function checkPermission($code){
$permissions = $this->getPermission();
$code_arr = explode(":",$code);
return $permissions->contains($code) || $permissions->contains($code_arr[0].":*");
}
}

View File

@ -36,6 +36,11 @@ class RouteServiceProvider extends ServiceProvider
->namespace("{$this->apiNamespace}\Auth")
->group(base_path('routes/auth.php'));
Route::middleware('api')
->prefix('accounting')
->namespace("{$this->apiNamespace}\Accounting")
->group(base_path('routes/accounting.php'));
Route::middleware('api')
->prefix('api')
->group(base_path('routes/api.php'));

View File

@ -0,0 +1,52 @@
<?php
namespace App\Repositories\Accounting;
use App\Models\Account;
use DB;
class AccountRepository
{
public function list($params){
$limit = @$params["limit"] ?? 10;
$offset = @$params["offset"] ?? 0;
$sortColumn = @$params["sort"]["column"] ?? "id";
$sortDir = @$params["sort"]["dir"] ?? "desc";
return Account::skip($offset)
->orderBy(DB::raw("structure::ltree"), "asc")
->when(@$params["filter"], function ($query) use ($params) {
foreach ($params["filter"] as $filter) {
$query->where($filter["column"], $filter["query"]);
}
})
->paginate($limit);
}
public function create($params){
$params["password"] = "-";
$model = Account::create($params);
if (@$params["permissions"]){
$model->permissions()->sync($params["permissions"]);
}
return $model;
}
public function update($model, $params){
$model->update($params);
if (@$params["permissions"]){
$model->permissions()->sync($params["permissions"]);
}
return $model;
}
public function delete($model){
$model->delete();
}
}

View File

@ -2,6 +2,7 @@
namespace App\Repositories\Auth;
use Illuminate\Validation\ValidationException;
use App\Models\User;
use Hash;

View File

@ -0,0 +1,49 @@
<?php
namespace App\Repositories\Auth;
use App\Models\Permission;
class PermissionRepository
{
public function list($params){
$limit = @$params["limit"] ?? 10;
$offset = @$params["offset"] ?? 0;
$sortColumn = @$params["sort"]["column"] ?? "id";
$sortDir = @$params["sort"]["dir"] ?? "desc";
$search = @$params["search"];
return Permission::skip($offset)
->orderBy($sortColumn, $sortDir)
->when($search, function ($query) use ($search){
$query->where(function($query) use ($search){
$query->where("name","ilike","%$search%");
$query->orWhere("code","ilike","%$search%");
});
})
->when(@$params["filter"], function ($query) use ($params) {
foreach ($params["filter"] as $filter) {
$query->where($filter["column"], $filter["query"]);
}
})
->paginate($limit);
}
public function create($params){
return $model;
}
public function update($model, $params){
return $model;
}
public function delete($model){
$model->delete();
}
}

View File

@ -0,0 +1,68 @@
<?php
namespace App\Repositories\Auth;
use App\Models\Role;
class RoleRepository
{
public function list($params){
$limit = @$params["limit"] ?? 10;
$offset = @$params["offset"] ?? 0;
$sortColumn = @$params["sort"]["column"] ?? "id";
$sortDir = @$params["sort"]["dir"] ?? "desc";
$search = @$params["search"] ?? 0;
return Role::skip($offset)
->orderBy($sortColumn, $sortDir)
->when($search, function ($query) use ($search){
$query->where(function($query) use ($search){
$query->where("name","ilike","%$search%");
$query->orWhere("code","ilike","%$search%");
});
})
->when(@$params["filter"], function ($query) use ($params) {
foreach ($params["filter"] as $filter) {
$query->where($filter["column"], $filter["query"]);
}
})
->paginate($limit);
}
public function create($params){
$params["password"] = "-";
$model = Role::create($params);
if (@$params["permissions"]){
$model->permissions()->sync($params["permissions"]);
}
return $model;
}
public function update($model, $params){
$model->update($params);
if (@$params["permissions"]){
$model->permissions()->sync($params["permissions"]);
}
foreach($model->users as $user){
$user->forgetPermission();
}
return $model;
}
public function delete($model){
foreach($model->users as $user){
$user->forgetPermission();
}
$model->delete();
}
}

View File

@ -0,0 +1,55 @@
<?php
namespace App\Repositories\Auth;
use App\Models\User;
class UserRepository
{
public function list($params){
$limit = @$params["limit"] ?? 10;
$offset = @$params["offset"] ?? 0;
$sortColumn = @$params["sort"]["column"] ?? "id";
$sortDir = @$params["sort"]["dir"] ?? "desc";
return User::skip($offset)
->orderBy($sortColumn, $sortDir)
->when(@$params["filter"], function ($query) use ($params) {
foreach ($params["filter"] as $filter) {
$query->where($filter["column"], $filter["query"]);
}
})
->paginate($limit);
}
public function create($params){
$params["password"] = "-";
$user = User::create($params);
if (@$params["roles"]){
$user->roles()->sync($params["roles"]);
$user->forgetPermission();
}
return $user;
}
public function update($user, $params){
$user->update($params);
if (@$params["roles"]){
$user->roles()->sync($params["roles"]);
$user->forgetPermission();
}
return $user;
}
public function delete($user){
$user->delete();
}
}

View File

@ -7,9 +7,11 @@
"require": {
"php": "^8.1",
"guzzlehttp/guzzle": "^7.2",
"laravel/envoy": "^2.10",
"laravel/framework": "^10.10",
"laravel/sanctum": "^3.3",
"laravel/tinker": "^2.8"
"laravel/tinker": "^2.8",
"spatie/laravel-activitylog": "^4.10"
},
"require-dev": {
"fakerphp/faker": "^1.9.1",

216
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "9c491b8531eec05ba41a11d9276a5749",
"content-hash": "2feee7537e769f923d55b248c506fe92",
"packages": [
{
"name": "brick/math",
@ -1054,6 +1054,69 @@
],
"time": "2023-12-03T19:50:20+00:00"
},
{
"name": "laravel/envoy",
"version": "v2.10.2",
"source": {
"type": "git",
"url": "https://github.com/laravel/envoy.git",
"reference": "819a519e3d86b056c7aa3bd5d0801952a6fc14fd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/envoy/zipball/819a519e3d86b056c7aa3bd5d0801952a6fc14fd",
"reference": "819a519e3d86b056c7aa3bd5d0801952a6fc14fd",
"shasum": ""
},
"require": {
"guzzlehttp/guzzle": "^6.0|^7.0",
"illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0",
"php": "^7.2|^8.0",
"symfony/console": "^4.3|^5.0|^6.0|^7.0",
"symfony/process": "^4.3|^5.0|^6.0|^7.0"
},
"require-dev": {
"phpstan/phpstan": "^1.10",
"phpunit/phpunit": "^8.0|^9.0|^10.4"
},
"suggest": {
"ext-posix": "Required to determine the System user on Unix systems."
},
"bin": [
"bin/envoy"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.x-dev"
}
},
"autoload": {
"psr-4": {
"Laravel\\Envoy\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
}
],
"description": "Elegant SSH tasks for PHP.",
"keywords": [
"laravel",
"ssh"
],
"support": {
"issues": "https://github.com/laravel/envoy/issues",
"source": "https://github.com/laravel/envoy/tree/v2.10.2"
},
"time": "2025-01-28T15:47:18+00:00"
},
{
"name": "laravel/framework",
"version": "v10.48.25",
@ -3181,6 +3244,157 @@
],
"time": "2024-04-27T21:32:50+00:00"
},
{
"name": "spatie/laravel-activitylog",
"version": "4.10.1",
"source": {
"type": "git",
"url": "https://github.com/spatie/laravel-activitylog.git",
"reference": "466f30f7245fe3a6e328ad5e6812bd43b4bddea5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/spatie/laravel-activitylog/zipball/466f30f7245fe3a6e328ad5e6812bd43b4bddea5",
"reference": "466f30f7245fe3a6e328ad5e6812bd43b4bddea5",
"shasum": ""
},
"require": {
"illuminate/config": "^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0",
"illuminate/database": "^8.69 || ^9.27 || ^10.0 || ^11.0 || ^12.0",
"illuminate/support": "^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0",
"php": "^8.1",
"spatie/laravel-package-tools": "^1.6.3"
},
"require-dev": {
"ext-json": "*",
"orchestra/testbench": "^6.23 || ^7.0 || ^8.0 || ^9.0 || ^10.0",
"pestphp/pest": "^1.20 || ^2.0 || ^3.0"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Spatie\\Activitylog\\ActivitylogServiceProvider"
]
}
},
"autoload": {
"files": [
"src/helpers.php"
],
"psr-4": {
"Spatie\\Activitylog\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Freek Van der Herten",
"email": "freek@spatie.be",
"homepage": "https://spatie.be",
"role": "Developer"
},
{
"name": "Sebastian De Deyne",
"email": "sebastian@spatie.be",
"homepage": "https://spatie.be",
"role": "Developer"
},
{
"name": "Tom Witkowski",
"email": "dev.gummibeer@gmail.com",
"homepage": "https://gummibeer.de",
"role": "Developer"
}
],
"description": "A very simple activity logger to monitor the users of your website or application",
"homepage": "https://github.com/spatie/activitylog",
"keywords": [
"activity",
"laravel",
"log",
"spatie",
"user"
],
"support": {
"issues": "https://github.com/spatie/laravel-activitylog/issues",
"source": "https://github.com/spatie/laravel-activitylog/tree/4.10.1"
},
"funding": [
{
"url": "https://spatie.be/open-source/support-us",
"type": "custom"
},
{
"url": "https://github.com/spatie",
"type": "github"
}
],
"time": "2025-02-10T15:38:25+00:00"
},
{
"name": "spatie/laravel-package-tools",
"version": "1.19.0",
"source": {
"type": "git",
"url": "https://github.com/spatie/laravel-package-tools.git",
"reference": "1c9c30ac6a6576b8d15c6c37b6cf23d748df2faa"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/1c9c30ac6a6576b8d15c6c37b6cf23d748df2faa",
"reference": "1c9c30ac6a6576b8d15c6c37b6cf23d748df2faa",
"shasum": ""
},
"require": {
"illuminate/contracts": "^9.28|^10.0|^11.0|^12.0",
"php": "^8.0"
},
"require-dev": {
"mockery/mockery": "^1.5",
"orchestra/testbench": "^7.7|^8.0|^9.0|^10.0",
"pestphp/pest": "^1.23|^2.1|^3.1",
"phpunit/phpunit": "^9.5.24|^10.5|^11.5",
"spatie/pest-plugin-test-time": "^1.1|^2.2"
},
"type": "library",
"autoload": {
"psr-4": {
"Spatie\\LaravelPackageTools\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Freek Van der Herten",
"email": "freek@spatie.be",
"role": "Developer"
}
],
"description": "Tools for creating Laravel packages",
"homepage": "https://github.com/spatie/laravel-package-tools",
"keywords": [
"laravel-package-tools",
"spatie"
],
"support": {
"issues": "https://github.com/spatie/laravel-package-tools/issues",
"source": "https://github.com/spatie/laravel-package-tools/tree/1.19.0"
},
"funding": [
{
"url": "https://github.com/spatie",
"type": "github"
}
],
"time": "2025-02-06T14:58:20+00:00"
},
{
"name": "symfony/console",
"version": "v6.4.17",

View File

@ -0,0 +1,29 @@
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Account>
*/
class AccountFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'name' => fake()->name(),
'code' => fake()->name(),
'sheet' => fake()->randomElement(["balance","income"]),
'type' => fake()->randomElement(["header","posting","begin-total","end-total"]),
'category' => fake()->name(),
'subcategory' => fake()->name(),
'structure' => str_replace(" ",".",strtolower(fake()->name())),
];
}
}

View File

@ -0,0 +1,23 @@
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Role>
*/
class RoleFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'name' => fake()->name(),
];
}
}

View File

@ -0,0 +1,35 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('accounts', function (Blueprint $table) {
$table->id();
$table->string('code')->unique();
$table->string('name');
$table->string('sheet'); // Balance/Income
$table->string('category')->nullable(); // Assets, Equity, Liabilities, Income, Expense, Cost of Goods
$table->string('subcategory')->nullable();
$table->string('type')->nullable(); // Header, Begin-Total, Posting, End-Total
$table->string('structure');
$table->string('totaling')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('accounts');
}
};

View File

@ -0,0 +1,26 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
DB::statement("CREATE EXTENSION IF NOT EXISTS ltree");
}
/**
* Reverse the migrations.
*/
public function down(): void
{
DB::statement("DROP EXTENSION ltree");
}
};

View File

@ -0,0 +1,27 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateActivityLogTable extends Migration
{
public function up()
{
Schema::connection(config('activitylog.database_connection'))->create(config('activitylog.table_name'), function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('log_name')->nullable();
$table->text('description');
$table->nullableMorphs('subject', 'subject');
$table->nullableMorphs('causer', 'causer');
$table->json('properties')->nullable();
$table->timestamps();
$table->index('log_name');
});
}
public function down()
{
Schema::connection(config('activitylog.database_connection'))->dropIfExists(config('activitylog.table_name'));
}
}

View File

@ -0,0 +1,22 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddEventColumnToActivityLogTable extends Migration
{
public function up()
{
Schema::connection(config('activitylog.database_connection'))->table(config('activitylog.table_name'), function (Blueprint $table) {
$table->string('event')->nullable()->after('subject_type');
});
}
public function down()
{
Schema::connection(config('activitylog.database_connection'))->table(config('activitylog.table_name'), function (Blueprint $table) {
$table->dropColumn('event');
});
}
}

View File

@ -0,0 +1,22 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddBatchUuidColumnToActivityLogTable extends Migration
{
public function up()
{
Schema::connection(config('activitylog.database_connection'))->table(config('activitylog.table_name'), function (Blueprint $table) {
$table->uuid('batch_uuid')->nullable()->after('properties');
});
}
public function down()
{
Schema::connection(config('activitylog.database_connection'))->table(config('activitylog.table_name'), function (Blueprint $table) {
$table->dropColumn('batch_uuid');
});
}
}

View File

@ -4,6 +4,7 @@ namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use DB;
class PermissionSeeder extends Seeder
{
@ -13,6 +14,21 @@ class PermissionSeeder extends Seeder
public function run(): void
{
$permissions = file_get_contents(__DIR__ . "/permissions.csv");
$permissions = explode("\n", $permissions);
$data = [];
foreach($permissions as $permission){
if ($permission == "")
continue;
$row = explode(",", $permission);
$data[] = [
"module" => $row[0],
"feature" => $row[1],
"action" => $row[2],
"code" => $row[3],
"name" => $row[4]
];
}
DB::table("permissions")->insertOrIgnore($data);
}
}

View File

@ -1,5 +1,15 @@
Auth,User,*,auth.user.*,All operation data user
Auth,User,*,auth.user.read,Show list data user
Auth,User,*,auth.user.create,Create data user
Auth,User,*,auth.user.update,Update data user
Auth,User,*,auth.user.delete,Delete data user
Auth,User,*,auth.user:*,All operation data user
Auth,User,*,auth.user:read,Show list data user
Auth,User,*,auth.user:create,Create data user
Auth,User,*,auth.user:update,Update data user
Auth,User,*,auth.user:delete,Delete data user
Auth,Role,*,auth.role:*,All operation data role
Auth,Role,*,auth.role:read,Show list data role
Auth,Role,*,auth.role:create,Create data role
Auth,Role,*,auth.role:update,Update data role
Auth,Role,*,auth.role:delete,Delete data role
Accounting,Account,*,accounting.account:*,All operation data account
Accounting,Account,*,accounting.account:read,Show list data account
Accounting,Account,*,accounting.account:create,Create data account
Accounting,Account,*,accounting.account:update,Update data account
Accounting,Account,*,accounting.account:delete,Delete data account

1 Auth User * auth.user.* auth.user:* All operation data user
2 Auth User * auth.user.read auth.user:read Show list data user
3 Auth User * auth.user.create auth.user:create Create data user
4 Auth User * auth.user.update auth.user:update Update data user
5 Auth User * auth.user.delete auth.user:delete Delete data user
6 Auth Role * auth.role:* All operation data role
7 Auth Role * auth.role:read Show list data role
8 Auth Role * auth.role:create Create data role
9 Auth Role * auth.role:update Update data role
10 Auth Role * auth.role:delete Delete data role
11 Accounting Account * accounting.account:* All operation data account
12 Accounting Account * accounting.account:read Show list data account
13 Accounting Account * accounting.account:create Create data account
14 Accounting Account * accounting.account:update Update data account
15 Accounting Account * accounting.account:delete Delete data account

11
routes/accounting.php Normal file
View File

@ -0,0 +1,11 @@
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
Route::group(["namespace" => "Account", "prefix" => "account", "middleware" => "auth:sanctum"], function () {
Route::get('/', 'ListController')->middleware("auth:sanctum");
Route::post('/', 'StoreController')->middleware("auth:sanctum");
Route::post('/{account}', 'UpdateController')->middleware("auth:sanctum");
Route::post('/{account}/delete', 'DeleteController')->middleware("auth:sanctum");
});

View File

@ -9,4 +9,21 @@ Route::get('current', 'CurrentController')->middleware("auth:sanctum");
Route::group(["namespace" => "User", "prefix" => "user", "middleware" => "auth:sanctum"], function () {
Route::get('/', 'ListController')->middleware("auth:sanctum");
Route::post('/', 'StoreController')->middleware("auth:sanctum");
Route::post('/{user}', 'UpdateController')->middleware("auth:sanctum");
Route::post('/{user}/delete', 'DeleteController')->middleware("auth:sanctum");
});
Route::group(["namespace" => "Role", "prefix" => "role", "middleware" => "auth:sanctum"], function () {
Route::get('/', 'ListController')->middleware("auth:sanctum");
Route::post('/', 'StoreController')->middleware("auth:sanctum");
Route::post('/{role}', 'UpdateController')->middleware("auth:sanctum");
Route::post('/{role}/delete', 'DeleteController')->middleware("auth:sanctum");
});
Route::group(["namespace" => "Permission", "prefix" => "permission", "middleware" => "auth:sanctum"], function () {
Route::get('/', 'ListController')->middleware("auth:sanctum");
});

View File

@ -0,0 +1,42 @@
<?php
namespace Tests\Feature\Accounting\Account;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
use App\Models\Account;
use App\Models\Role;
use App\Models\Permission;
use App\Models\User;
use Laravel\Sanctum\Sanctum;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class DeleteTest extends TestCase
{
use DatabaseTransactions;
/**
* A basic feature test example.
*/
public function test_success(): void
{
$permission = Permission::where("code","accounting.account:delete")->first();
$role = Role::factory()->create();
$role->permissions()->attach($permission->id);
$user = User::factory()->create();
$user->roles()->attach($role->id);
Sanctum::actingAs($user);
$data = Account::factory()->create();
$response = $this->post('/accounting/account/'.$data->id.'/delete');
$response->assertStatus(200);
}
}

View File

@ -0,0 +1,49 @@
<?php
namespace Tests\Feature\Accounting\Account;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
use App\Models\Account;
use App\Models\Role;
use App\Models\Permission;
use App\Models\User;
use Laravel\Sanctum\Sanctum;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ListTest extends TestCase
{
use DatabaseTransactions;
/**
* A basic feature test example.
*/
public function test_success(): void
{
$permission = Permission::where("code","accounting.account:read")->first();
$role = Role::factory()->create();
$role->permissions()->attach($permission->id);
$user = User::factory()->create();
$user->roles()->attach($role->id);
Sanctum::actingAs($user);
$data = Account::factory()->create();
$response = $this->get('/accounting/account/');
$response->assertStatus(200);
$response->assertJson([
"data" => [
[
"id" => $data->id,
"name" => $data->name
]
]
]);
}
}

View File

@ -0,0 +1,89 @@
<?php
namespace Tests\Feature\Accounting\Account;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
use App\Models\Role;
use App\Models\User;
use App\Models\Permission;
use App\Models\Account;
use Laravel\Sanctum\Sanctum;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class StoreTest extends TestCase
{
use DatabaseTransactions;
/**
* A basic feature test example.
*/
public function test_success(): void
{
$permission = Permission::where("code","accounting.account:create")->first();
$role = Role::factory()->create();
$role->permissions()->attach($permission->id);
$user = User::factory()->create();
$user->roles()->attach($role->id);
Sanctum::actingAs($user);
$response = $this->post('/accounting/account/',[
"name" => "new role",
"code" => "code",
"sheet" => "sheet",
"structure" => "structure",
"type" => "type",
"category" => "category",
"subcategory" => "subcategory",
]);
$response->assertStatus(201);
$response->assertJson([
"data" => [
"name" => "new role"
]
]);
}
/**
* A basic feature test example.
*/
public function test_with_roles_success(): void
{
$permission = Permission::where("code","accounting.account:create")->first();
$role = Role::factory()->create();
$role->permissions()->attach($permission->id);
$user = User::factory()->create();
$user->roles()->attach($role->id);
$role2 = Role::factory()->create();
Sanctum::actingAs($user);
$response = $this->post('/accounting/account/',[
"name" => "new role",
"code" => "code",
"sheet" => "sheet",
"structure" => "structure",
"type" => "type",
"category" => "category",
"subcategory" => "subcategory",
]);
$response->assertStatus(201);
$response->assertJson([
"data" => [
"name" => "new role"
]
]);
}
}

View File

@ -0,0 +1,92 @@
<?php
namespace Tests\Feature\Accounting\Account;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
use App\Models\Account;
use App\Models\Role;
use App\Models\Permission;
use App\Models\User;
use Laravel\Sanctum\Sanctum;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class UpdateTest extends TestCase
{
use DatabaseTransactions;
/**
* A basic feature test example.
*/
public function test_success(): void
{
$permission = Permission::where("code","accounting.account:update")->first();
$role = Role::factory()->create();
$role->permissions()->attach($permission->id);
$user = User::factory()->create();
$user->roles()->attach($role->id);
Sanctum::actingAs($user);
$data = Account::factory()->create();
$response = $this->post('/accounting/account/'.$data->id,[
"name" => "update role",
"code" => "code",
"sheet" => "sheet",
"structure" => "structure",
"type" => "type",
"category" => "category",
"subcategory" => "subcategory",
]);
$response->assertStatus(200);
$response->assertJson([
"data" => [
"name" => "update role",
]
]);
}
/**
* A basic feature test example.
*/
public function test_with_roles_success(): void
{
$permission = Permission::where("code","accounting.account:update")->first();
$role = Role::factory()->create();
$role->permissions()->attach($permission->id);
$user = User::factory()->create();
$user->roles()->attach($role->id);
Sanctum::actingAs($user);
$data = Account::factory()->create();
$role2 = Role::factory()->create();
$response = $this->post('/accounting/account/'.$data->id,[
"name" => "update role",
"code" => "code",
"sheet" => "sheet",
"structure" => "structure",
"type" => "type",
"category" => "category",
"subcategory" => "subcategory",
]);
$response->assertStatus(200);
$response->assertJson([
"data" => [
"name" => "update role"
]
]);
}
}

View File

@ -26,4 +26,19 @@ class LoginTest extends TestCase
$response->assertStatus(200);
}
/**
* A basic feature test example.
*/
public function test_fail(): void
{
$user = User::factory()->create();
$response = $this->post('/auth/login',[
"email" => $user->email,
"password" => "fail",
]);
$response->assertStatus(422);
}
}

View File

@ -0,0 +1,46 @@
<?php
namespace Tests\Feature\Auth\Permission;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
use App\Models\Role;
use App\Models\Permission;
use App\Models\User;
use Laravel\Sanctum\Sanctum;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ListTest extends TestCase
{
use DatabaseTransactions;
/**
* A basic feature test example.
*/
public function test_success(): void
{
$permission = Permission::where("code","auth.role:read")->first();
$role = Role::factory()->create();
$role->permissions()->attach($permission->id);
$user = User::factory()->create();
$user->roles()->attach($role->id);
Sanctum::actingAs($user);
$response = $this->get('/auth/permission?search=auth.role:read');
$response->assertStatus(200);
$response->assertJson([
"data" => [
[
"id" => $permission->id,
"name" => $permission->name
]
]
]);
}
}

View File

@ -0,0 +1,40 @@
<?php
namespace Tests\Feature\Auth\Role;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
use App\Models\Role;
use App\Models\Permission;
use App\Models\User;
use Laravel\Sanctum\Sanctum;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class DeleteTest extends TestCase
{
use DatabaseTransactions;
/**
* A basic feature test example.
*/
public function test_success(): void
{
$permission = Permission::where("code","auth.role:delete")->first();
$role = Role::factory()->create();
$role->permissions()->attach($permission->id);
$user = User::factory()->create();
$user->roles()->attach($role->id);
Sanctum::actingAs($user);
$data = Role::factory()->create();
$response = $this->post('/auth/role/'.$data->id.'/delete');
$response->assertStatus(200);
}
}

View File

@ -0,0 +1,46 @@
<?php
namespace Tests\Feature\Auth\Role;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
use App\Models\Role;
use App\Models\Permission;
use App\Models\User;
use Laravel\Sanctum\Sanctum;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ListTest extends TestCase
{
use DatabaseTransactions;
/**
* A basic feature test example.
*/
public function test_success(): void
{
$permission = Permission::where("code","auth.role:read")->first();
$role = Role::factory()->create();
$role->permissions()->attach($permission->id);
$user = User::factory()->create();
$user->roles()->attach($role->id);
Sanctum::actingAs($user);
$response = $this->get('/auth/role/');
$response->assertStatus(200);
$response->assertJson([
"data" => [
[
"id" => $role->id,
"name" => $role->name
]
]
]);
}
}

View File

@ -0,0 +1,82 @@
<?php
namespace Tests\Feature\Auth\Role;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
use App\Models\Role;
use App\Models\User;
use App\Models\Permission;
use Laravel\Sanctum\Sanctum;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class StoreTest extends TestCase
{
use DatabaseTransactions;
/**
* A basic feature test example.
*/
public function test_success(): void
{
$permission = Permission::where("code","auth.role:create")->first();
$role = Role::factory()->create();
$role->permissions()->attach($permission->id);
$user = User::factory()->create();
$user->roles()->attach($role->id);
Sanctum::actingAs($user);
$response = $this->post('/auth/role/',[
"name" => "new role"
]);
$response->assertStatus(201);
$response->assertJson([
"data" => [
"name" => "new role"
]
]);
}
/**
* A basic feature test example.
*/
public function test_with_roles_success(): void
{
$permission = Permission::where("code","auth.role:create")->first();
$role = Role::factory()->create();
$role->permissions()->attach($permission->id);
$user = User::factory()->create();
$user->roles()->attach($role->id);
$role2 = Role::factory()->create();
Sanctum::actingAs($user);
$response = $this->post('/auth/role/',[
"name" => "new role",
"permissions" => [$permission->id]
]);
$response->assertStatus(201);
$response->assertJson([
"data" => [
"name" => "new role",
"permissions" => [
[
"id" => $permission->id
],
]
]
]);
}
}

View File

@ -0,0 +1,85 @@
<?php
namespace Tests\Feature\Auth\Role;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
use App\Models\Role;
use App\Models\Permission;
use App\Models\User;
use Laravel\Sanctum\Sanctum;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class UpdateTest extends TestCase
{
use DatabaseTransactions;
/**
* A basic feature test example.
*/
public function test_success(): void
{
$permission = Permission::where("code","auth.role:update")->first();
$role = Role::factory()->create();
$role->permissions()->attach($permission->id);
$user = User::factory()->create();
$user->roles()->attach($role->id);
Sanctum::actingAs($user);
$data = Role::factory()->create();
$response = $this->post('/auth/role/'.$data->id,[
"name" => "update role",
]);
$response->assertStatus(200);
$response->assertJson([
"data" => [
"name" => "update role",
]
]);
}
/**
* A basic feature test example.
*/
public function test_with_roles_success(): void
{
$permission = Permission::where("code","auth.role:update")->first();
$role = Role::factory()->create();
$role->permissions()->attach($permission->id);
$user = User::factory()->create();
$user->roles()->attach($role->id);
Sanctum::actingAs($user);
$data = Role::factory()->create();
$role2 = Role::factory()->create();
$response = $this->post('/auth/role/'.$data->id,[
"name" => "update role",
"permissions" => [
$permission->id
]
]);
$response->assertStatus(200);
$response->assertJson([
"data" => [
"name" => "update role",
"permissions" => [
[
"id" => $permission->id
]
]
]
]);
}
}

View File

@ -0,0 +1,40 @@
<?php
namespace Tests\Feature\Auth\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
use App\Models\Role;
use App\Models\Permission;
use App\Models\User;
use Laravel\Sanctum\Sanctum;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class DeleteTest extends TestCase
{
use DatabaseTransactions;
/**
* A basic feature test example.
*/
public function test_success(): void
{
$permission = Permission::where("code","auth.user:delete")->first();
$role = Role::factory()->create();
$role->permissions()->attach($permission->id);
$user = User::factory()->create();
$user->roles()->attach($role->id);
Sanctum::actingAs($user);
$data = User::factory()->create();
$response = $this->post('/auth/user/'.$data->id.'/delete');
$response->assertStatus(200);
}
}

View File

@ -12,18 +12,42 @@ use App\Models\Permission;
use App\Models\User;
use Laravel\Sanctum\Sanctum;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ListTest extends TestCase
{
use DatabaseTransactions;
/**
* A basic feature test example.
*/
public function test_success(): void
{
$permission = Permission::where("code","auth.user:read")->first();
$role = Role::factory()->create();
$role->permissions()->attach($permission->id);
$user = User::factory()->create();
$user->roles()->attach($role->id);
Sanctum::actingAs($user);
$response = $this->get('/auth/user/');
$response->assertStatus(200);
$response->assertJson([
"data" => [
[
"id" => $user->id,
"name" => $user->name,
"email" => $user->email,
"roles" => [
[
"id" => $role->id,
"name" => $role->name
]
]
]
]
]);
}
}

View File

@ -0,0 +1,87 @@
<?php
namespace Tests\Feature\Auth\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
use App\Models\Role;
use App\Models\Permission;
use App\Models\User;
use Laravel\Sanctum\Sanctum;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class StoreTest extends TestCase
{
use DatabaseTransactions;
/**
* A basic feature test example.
*/
public function test_success(): void
{
$permission = Permission::where("code","auth.user:create")->first();
$role = Role::factory()->create();
$role->permissions()->attach($permission->id);
$user = User::factory()->create();
$user->roles()->attach($role->id);
Sanctum::actingAs($user);
$response = $this->post('/auth/user/',[
"name" => "new user",
"email" => "user@gmail.com"
]);
$response->assertStatus(201);
$response->assertJson([
"data" => [
"name" => "new user",
"email" => "user@gmail.com"
]
]);
}
/**
* A basic feature test example.
*/
public function test_with_roles_success(): void
{
$permission = Permission::where("code","auth.user:create")->first();
$role = Role::factory()->create();
$role->permissions()->attach($permission->id);
$user = User::factory()->create();
$user->roles()->attach($role->id);
$role2 = Role::factory()->create();
Sanctum::actingAs($user);
$response = $this->post('/auth/user/',[
"name" => "new user",
"email" => "user@gmail.com",
"roles" => [$role->id, $role2->id]
]);
$response->assertStatus(201);
$response->assertJson([
"data" => [
"name" => "new user",
"email" => "user@gmail.com",
"roles" => [
[
"id" => $role->id
],
[
"id" => $role2->id
],
]
]
]);
}
}

View File

@ -0,0 +1,91 @@
<?php
namespace Tests\Feature\Auth\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
use App\Models\Role;
use App\Models\Permission;
use App\Models\User;
use Laravel\Sanctum\Sanctum;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class UpdateTest extends TestCase
{
use DatabaseTransactions;
/**
* A basic feature test example.
*/
public function test_success(): void
{
$permission = Permission::where("code","auth.user:update")->first();
$role = Role::factory()->create();
$role->permissions()->attach($permission->id);
$user = User::factory()->create();
$user->roles()->attach($role->id);
Sanctum::actingAs($user);
$data = User::factory()->create();
$response = $this->post('/auth/user/'.$data->id,[
"name" => "update user",
"email" => "user_update@gmail.com"
]);
$response->assertStatus(200);
$response->assertJson([
"data" => [
"name" => "update user",
"email" => "user_update@gmail.com"
]
]);
}
/**
* A basic feature test example.
*/
public function test_with_roles_success(): void
{
$permission = Permission::where("code","auth.user:update")->first();
$role = Role::factory()->create();
$role->permissions()->attach($permission->id);
$user = User::factory()->create();
$user->roles()->attach($role->id);
Sanctum::actingAs($user);
$data = User::factory()->create();
$role2 = Role::factory()->create();
$response = $this->post('/auth/user/'.$data->id,[
"name" => "update user",
"email" => "user_update@gmail.com",
"roles" => [
$role->id, $role2->id
]
]);
$response->assertStatus(200);
$response->assertJson([
"data" => [
"name" => "update user",
"email" => "user_update@gmail.com",
"roles" => [
[
"id" => $role->id
],
[
"id" => $role2->id
],
]
]
]);
}
}