Compare commits
2 Commits
97495f9991
...
782dbd4aaa
| Author | SHA1 | Date |
|---|---|---|
|
|
782dbd4aaa | 2 months ago |
|
|
b2e90078bb | 2 months ago |
301 changed files with 7428 additions and 272 deletions
@ -0,0 +1,21 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Academic\Actions\Calendar; |
||||
|
|
||||
|
use App\Domains\Academic\DTOs\Calendar\InitializeAcademicTermDTO; |
||||
|
use App\Domains\Academic\Models\Term; |
||||
|
|
||||
|
class InitializeAcademicTerm |
||||
|
{ |
||||
|
public function execute(InitializeAcademicTermDTO $dto): void |
||||
|
{ |
||||
|
Term::create([ |
||||
|
'name' => $dto->name, |
||||
|
'code' => $dto->code, |
||||
|
'year_study' => $dto->yearStudy, |
||||
|
'semester' => $dto->semester, |
||||
|
'date_start' => $dto->startDate, |
||||
|
'date_end' => $dto->endDate, |
||||
|
]); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Academic\Actions\Calendar; |
||||
|
|
||||
|
use App\Domains\Academic\DTOs\Calendar\ModifyTermDTO; |
||||
|
use App\Domains\Academic\Models\Term; |
||||
|
|
||||
|
class ModifyTerm |
||||
|
{ |
||||
|
public function execute(Term $term, ModifyTermDTO $dto): void |
||||
|
{ |
||||
|
$term->update([ |
||||
|
'date_start' => $dto->startDate, |
||||
|
'date_end' => $dto->endDate, |
||||
|
]); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Academic\Actions\Calendar; |
||||
|
|
||||
|
use App\Domains\Academic\DTOs\Calendar\ModifyTermDateDTO; |
||||
|
use App\Domains\Academic\Models\Term; |
||||
|
|
||||
|
class ModifyTermDate |
||||
|
{ |
||||
|
public function execute(Term $term, ModifyTermDateDTO $dto): void |
||||
|
{ |
||||
|
$term->update([ |
||||
|
'date_start' => $dto->startDate, |
||||
|
'date_end' => $dto->endDate, |
||||
|
]); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Academic\Actions\Curriculum; |
||||
|
|
||||
|
use App\Domains\Academic\DTOs\Curriculum\AdjustStudyProgramDTO; |
||||
|
use App\Domains\Academic\Models\StudyProgram; |
||||
|
|
||||
|
class AdjustStudyProgramDetails |
||||
|
{ |
||||
|
public function execute(StudyProgram $studyProgram, AdjustStudyProgramDTO $dto): void |
||||
|
{ |
||||
|
$studyProgram->update([ |
||||
|
'level' => $dto->level, |
||||
|
'status' => $dto->status, |
||||
|
]); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Academic\Actions\Curriculum; |
||||
|
|
||||
|
use App\Domains\Academic\DTOs\Curriculum\EstablishFacultyDTO; |
||||
|
use App\Domains\Academic\Models\Faculty; |
||||
|
|
||||
|
class EstablishFaculty |
||||
|
{ |
||||
|
public function execute(EstablishFacultyDTO $dto): void |
||||
|
{ |
||||
|
Faculty::create([ |
||||
|
'name' => $dto->name, |
||||
|
'code' => $dto->code, |
||||
|
'external_id' => $dto->externalId, |
||||
|
]); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Academic\Actions\Curriculum; |
||||
|
|
||||
|
use App\Domains\Academic\DTOs\Curriculum\ModifyFacultyDetailsDTO; |
||||
|
use App\Domains\Academic\Models\Faculty; |
||||
|
|
||||
|
class ModifyFacultyDetails |
||||
|
{ |
||||
|
public function execute(Faculty $faculty, ModifyFacultyDetailsDTO $dto): void |
||||
|
{ |
||||
|
$faculty->update([ |
||||
|
'name' => $dto->name, |
||||
|
'code' => $dto->code, |
||||
|
]); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,21 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Academic\Actions\Curriculum; |
||||
|
|
||||
|
use App\Domains\Academic\DTOs\Curriculum\RegisterStudyProgramDTO; |
||||
|
use App\Domains\Academic\Models\StudyProgram; |
||||
|
|
||||
|
class RegisterStudyProgram |
||||
|
{ |
||||
|
public function execute(RegisterStudyProgramDTO $dto): void |
||||
|
{ |
||||
|
StudyProgram::create([ |
||||
|
'name' => $dto->name, |
||||
|
'code' => $dto->code, |
||||
|
'level' => $dto->level, |
||||
|
'status' => $dto->status, |
||||
|
'faculty_id' => $dto->facultyId, |
||||
|
'external_id' => $dto->externalId, |
||||
|
]); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Academic\DTOs\Calendar; |
||||
|
|
||||
|
use Carbon\CarbonImmutable; |
||||
|
|
||||
|
readonly class InitializeAcademicTermDTO |
||||
|
{ |
||||
|
public function __construct( |
||||
|
public string $name, |
||||
|
public string $code, |
||||
|
public string $yearStudy, |
||||
|
public string $semester, |
||||
|
public CarbonImmutable $startDate, |
||||
|
public CarbonImmutable $endDate, |
||||
|
) {} |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Academic\DTOs\Calendar; |
||||
|
|
||||
|
use Carbon\CarbonImmutable; |
||||
|
|
||||
|
readonly class ModifyTermDTO |
||||
|
{ |
||||
|
public function __construct( |
||||
|
public CarbonImmutable $startDate, |
||||
|
public CarbonImmutable $endDate, |
||||
|
) {} |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Academic\DTOs\Calendar; |
||||
|
|
||||
|
use Carbon\CarbonImmutable; |
||||
|
|
||||
|
readonly class ModifyTermDateDTO |
||||
|
{ |
||||
|
public function __construct( |
||||
|
public CarbonImmutable $startDate, |
||||
|
public CarbonImmutable $endDate, |
||||
|
) {} |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Academic\DTOs\Curriculum; |
||||
|
|
||||
|
use App\Domains\System\Enums\LifecycleStatus; |
||||
|
|
||||
|
readonly class AdjustStudyProgramDTO |
||||
|
{ |
||||
|
public function __construct( |
||||
|
public string $level, |
||||
|
public LifecycleStatus $status, |
||||
|
) {} |
||||
|
} |
||||
@ -0,0 +1,12 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Academic\DTOs\Curriculum; |
||||
|
|
||||
|
readonly class EstablishFacultyDTO |
||||
|
{ |
||||
|
public function __construct( |
||||
|
public string $name, |
||||
|
public string $code, |
||||
|
public ?string $externalId = null |
||||
|
) {} |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Academic\DTOs\Curriculum; |
||||
|
|
||||
|
readonly class ModifyFacultyDetailsDTO |
||||
|
{ |
||||
|
public function __construct( |
||||
|
public string $name, |
||||
|
public string $code |
||||
|
) {} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Academic\DTOs\Curriculum; |
||||
|
|
||||
|
use App\Domains\System\Enums\LifecycleStatus; |
||||
|
|
||||
|
readonly class RegisterStudyProgramDTO |
||||
|
{ |
||||
|
public function __construct( |
||||
|
public string $name, |
||||
|
public string $code, |
||||
|
public string $level, |
||||
|
public LifecycleStatus $status, |
||||
|
public int $facultyId, |
||||
|
public int $externalId, |
||||
|
) {} |
||||
|
} |
||||
@ -0,0 +1,35 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Academic\Models; |
||||
|
|
||||
|
use App\Domains\Academic\Policies\FacultyPolicy; |
||||
|
use App\Domains\System\Enums\LifecycleStatus; |
||||
|
use Database\Factories\Academic\FacultyFactory; |
||||
|
use Illuminate\Database\Eloquent\Attributes\Fillable; |
||||
|
use Illuminate\Database\Eloquent\Attributes\UsePolicy; |
||||
|
use Illuminate\Database\Eloquent\Concerns\HasUlids; |
||||
|
use Illuminate\Database\Eloquent\Factories\Factory; |
||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory; |
||||
|
use Illuminate\Database\Eloquent\Model; |
||||
|
|
||||
|
#[Fillable(['name', 'code', 'status', 'external_id'])] |
||||
|
#[UsePolicy(FacultyPolicy::class)] |
||||
|
class Faculty extends Model |
||||
|
{ |
||||
|
use HasFactory; |
||||
|
use HasUlids; |
||||
|
|
||||
|
protected $casts = [ |
||||
|
'status' => LifecycleStatus::class, |
||||
|
]; |
||||
|
|
||||
|
protected static function newFactory(): Factory |
||||
|
{ |
||||
|
return FacultyFactory::new(); |
||||
|
} |
||||
|
|
||||
|
public function uniqueIds(): array |
||||
|
{ |
||||
|
return ['ulid']; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,48 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Academic\Models; |
||||
|
|
||||
|
use App\Domains\Academic\Policies\StudyProgramPolicy; |
||||
|
use App\Domains\System\Enums\LifecycleStatus; |
||||
|
use Database\Factories\Academic\StudyProgramFactory; |
||||
|
use Illuminate\Database\Eloquent\Attributes\Fillable; |
||||
|
use Illuminate\Database\Eloquent\Attributes\UsePolicy; |
||||
|
use Illuminate\Database\Eloquent\Concerns\HasUlids; |
||||
|
use Illuminate\Database\Eloquent\Factories\Factory; |
||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory; |
||||
|
use Illuminate\Database\Eloquent\Model; |
||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo; |
||||
|
|
||||
|
#[Fillable([ |
||||
|
'name', |
||||
|
'code', |
||||
|
'level', |
||||
|
'status', |
||||
|
'faculty_id', |
||||
|
'external_id', |
||||
|
])] |
||||
|
#[UsePolicy(StudyProgramPolicy::class)] |
||||
|
class StudyProgram extends Model |
||||
|
{ |
||||
|
use HasFactory; |
||||
|
use HasUlids; |
||||
|
|
||||
|
protected $casts = [ |
||||
|
'status' => LifecycleStatus::class, |
||||
|
]; |
||||
|
|
||||
|
protected static function newFactory(): Factory |
||||
|
{ |
||||
|
return StudyProgramFactory::new(); |
||||
|
} |
||||
|
|
||||
|
public function uniqueIds(): array |
||||
|
{ |
||||
|
return ['ulid']; |
||||
|
} |
||||
|
|
||||
|
public function faculty(): BelongsTo |
||||
|
{ |
||||
|
return $this->belongsTo(Faculty::class); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Academic\Models; |
||||
|
|
||||
|
use App\Domains\Academic\Policies\TermPolicy; |
||||
|
use Database\Factories\Academic\TermFactory; |
||||
|
use Illuminate\Database\Eloquent\Attributes\Fillable; |
||||
|
use Illuminate\Database\Eloquent\Attributes\UsePolicy; |
||||
|
use Illuminate\Database\Eloquent\Concerns\HasUlids; |
||||
|
use Illuminate\Database\Eloquent\Factories\Factory; |
||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory; |
||||
|
use Illuminate\Database\Eloquent\Model; |
||||
|
|
||||
|
#[Fillable(['name', 'code', 'year_study', 'semester', 'date_start', 'date_end'])] |
||||
|
#[UsePolicy(TermPolicy::class)] |
||||
|
class Term extends Model |
||||
|
{ |
||||
|
use HasFactory; |
||||
|
use HasUlids; |
||||
|
|
||||
|
protected static function newFactory(): Factory |
||||
|
{ |
||||
|
return TermFactory::new(); |
||||
|
} |
||||
|
|
||||
|
public function uniqueIds(): array |
||||
|
{ |
||||
|
return ['ulid']; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,49 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Academic\Policies; |
||||
|
|
||||
|
use App\Domains\Academic\Models\Faculty; |
||||
|
use App\Domains\Identity\Models\User; |
||||
|
|
||||
|
class FacultyPolicy |
||||
|
{ |
||||
|
/** |
||||
|
* Determine whether the user can view any models. |
||||
|
*/ |
||||
|
public function viewAny(User $user): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('faculty.viewAny'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can view the model. |
||||
|
*/ |
||||
|
public function view(User $user, Faculty $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('faculty.view'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can create models. |
||||
|
*/ |
||||
|
public function create(User $user): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('faculty.create'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can update the model. |
||||
|
*/ |
||||
|
public function update(User $user, Faculty $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('faculty.update'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can delete the model. |
||||
|
*/ |
||||
|
public function delete(User $user, Faculty $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('faculty.delete'); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,49 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Academic\Policies; |
||||
|
|
||||
|
use App\Domains\Academic\Models\StudyProgram; |
||||
|
use App\Domains\Identity\Models\User; |
||||
|
|
||||
|
class StudyProgramPolicy |
||||
|
{ |
||||
|
/** |
||||
|
* Determine whether the user can view any models. |
||||
|
*/ |
||||
|
public function viewAny(User $user): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('study-program.viewAny'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can view the model. |
||||
|
*/ |
||||
|
public function view(User $user, StudyProgram $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('study-program.view'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can create models. |
||||
|
*/ |
||||
|
public function create(User $user): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('study-program.create'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can update the model. |
||||
|
*/ |
||||
|
public function update(User $user, StudyProgram $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('study-program.update'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can delete the model. |
||||
|
*/ |
||||
|
public function delete(User $user, StudyProgram $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('study-program.delete'); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,49 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Academic\Policies; |
||||
|
|
||||
|
use App\Domains\Academic\Models\Term; |
||||
|
use App\Domains\Identity\Models\User; |
||||
|
|
||||
|
class TermPolicy |
||||
|
{ |
||||
|
/** |
||||
|
* Determine whether the user can view any models. |
||||
|
*/ |
||||
|
public function viewAny(User $user): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('term.viewAny'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can view the model. |
||||
|
*/ |
||||
|
public function view(User $user, Term $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('term.view'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can create models. |
||||
|
*/ |
||||
|
public function create(User $user): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('term.create'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can update the model. |
||||
|
*/ |
||||
|
public function update(User $user, Term $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('term.update'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can delete the model. |
||||
|
*/ |
||||
|
public function delete(User $user, Term $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('term.delete'); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Academic\Providers; |
||||
|
|
||||
|
use App\Domains\System\Traits\Provider\RegistersDomainEvents; |
||||
|
use Illuminate\Support\ServiceProvider; |
||||
|
|
||||
|
class AcademicServiceProvider extends ServiceProvider |
||||
|
{ |
||||
|
use RegistersDomainEvents; |
||||
|
|
||||
|
protected array $listen = []; |
||||
|
|
||||
|
public function register(): void |
||||
|
{ |
||||
|
$this->app->register(RelationshipServiceProvider::class); |
||||
|
} |
||||
|
|
||||
|
public function boot(): void |
||||
|
{ |
||||
|
$this->registerEvents(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,54 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Academic\Providers; |
||||
|
|
||||
|
use App\Domains\Academic\Models\StudyProgram; |
||||
|
use App\Domains\Academic\Models\Term; |
||||
|
use App\Domains\Admission\Models\AdmissionSchedule; |
||||
|
use App\Domains\Admission\Models\FeeRate; |
||||
|
use Illuminate\Support\ServiceProvider; |
||||
|
|
||||
|
class RelationshipServiceProvider extends ServiceProvider |
||||
|
{ |
||||
|
/** |
||||
|
* Boot cross-domain runtime relationships. |
||||
|
* |
||||
|
* This provider is strictly dedicated to runtime, decoupled cross-domain |
||||
|
* relationship definitions. Use Model::resolveRelationUsing() here to wire |
||||
|
* explicit polymorphic or foreign-key macros between models that live in |
||||
|
* different domains — without introducing a hard compile-time dependency |
||||
|
* between those domains. |
||||
|
* |
||||
|
* Do NOT add route registrations, bindings, event listeners, or any other |
||||
|
* bootstrapping logic here. Keep this file focused on relationships only. |
||||
|
* |
||||
|
* Example: |
||||
|
* |
||||
|
* Order::resolveRelationUsing('customer', fn (Order $order) => |
||||
|
* $order->belongsTo(Customer::class, 'customer_id') |
||||
|
* ); |
||||
|
*/ |
||||
|
public function boot(): void |
||||
|
{ |
||||
|
// Register cross-domain relationships below. |
||||
|
AdmissionSchedule::resolveRelationUsing('term', fn (AdmissionSchedule $admissionSchedule) => $admissionSchedule->belongsTo( |
||||
|
related: Term::class, |
||||
|
foreignKey: 'term_id' |
||||
|
)); |
||||
|
Term::resolveRelationUsing('admission_schedules', fn (Term $term) => $term->hasMany( |
||||
|
related: AdmissionSchedule::class, |
||||
|
foreignKey: 'term_id', |
||||
|
localKey: 'id' |
||||
|
)); |
||||
|
|
||||
|
FeeRate::resolveRelationUsing('study_program', fn (FeeRate $feeRate) => $feeRate->belongsTo( |
||||
|
related: StudyProgram::class, |
||||
|
foreignKey: 'study_program_id' |
||||
|
)); |
||||
|
StudyProgram::resolveRelationUsing('fee_rates', fn (StudyProgram $studyProgram) => $studyProgram->hasMany( |
||||
|
related: FeeRate::class, |
||||
|
foreignKey: 'study_program_id', |
||||
|
localKey: 'id' |
||||
|
)); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Admission\Actions\AdmissionPricing; |
||||
|
|
||||
|
use App\Domains\Admission\DTOs\AdmissionPricing\FeeTypeDTO; |
||||
|
use App\Domains\Admission\Models\FeeType; |
||||
|
|
||||
|
class DefineFeeType |
||||
|
{ |
||||
|
public function execute(FeeTypeDTO $dto): void |
||||
|
{ |
||||
|
FeeType::create([ |
||||
|
'name' => $dto->name, |
||||
|
'billing_cycle' => $dto->billingCycle, |
||||
|
]); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Admission\Actions\AdmissionPricing; |
||||
|
|
||||
|
class SetUpAdmissionFeeRates |
||||
|
{ |
||||
|
public function execute(): void |
||||
|
{ |
||||
|
// |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Admission\Actions\IntakeScheduling; |
||||
|
|
||||
|
use App\Domains\Admission\DTOs\IntakeScheduling\AdjustAdmissionScheduleDurationDTO; |
||||
|
use App\Domains\Admission\Models\AdmissionSchedule; |
||||
|
|
||||
|
class AdjustAdmissionScheduleDuration |
||||
|
{ |
||||
|
public function execute(AdmissionSchedule $admissionSchedule, AdjustAdmissionScheduleDurationDTO $dto): void |
||||
|
{ |
||||
|
$admissionSchedule->update([ |
||||
|
'date_start' => $dto->startData, |
||||
|
'date_end' => $dto->endData, |
||||
|
're_registration_date_start' => $dto->reRegisterStartData, |
||||
|
're_registration_date_end' => $dto->reRegisterEndData, |
||||
|
]); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Admission\Actions\IntakeScheduling; |
||||
|
|
||||
|
use App\Domains\Admission\DTOs\IntakeScheduling\PublishAdmissionScheduleDTO; |
||||
|
use App\Domains\Admission\Models\AdmissionSchedule; |
||||
|
|
||||
|
class PublishAdmissionSchedule |
||||
|
{ |
||||
|
public function execute(PublishAdmissionScheduleDTO $dto): void |
||||
|
{ |
||||
|
AdmissionSchedule::create([ |
||||
|
'date_start' => $dto->startData, |
||||
|
'date_end' => $dto->endData, |
||||
|
're_registration_date_start' => $dto->reRegisterStartData, |
||||
|
're_registration_date_end' => $dto->reRegisterEndData, |
||||
|
'status' => $dto->status, |
||||
|
'term_id' => $dto->termId, |
||||
|
'admission_track_id' => $dto->admissionTrackId, |
||||
|
]); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Admission\Actions\IntakeSourcing; |
||||
|
|
||||
|
use App\Domains\Admission\DTOs\IntakeSourcing\InitializeAdmissionTrackDTO; |
||||
|
use App\Domains\Admission\Models\AdmissionTrack; |
||||
|
|
||||
|
class InitializeAdmissionTrack |
||||
|
{ |
||||
|
public function execute(InitializeAdmissionTrackDTO $dto): void |
||||
|
{ |
||||
|
AdmissionTrack::create([ |
||||
|
'name' => $dto->name, |
||||
|
'status' => $dto->status, |
||||
|
]); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Admission\Actions\StudyModeProvisioning; |
||||
|
|
||||
|
use App\Domains\Admission\DTOs\StudyModeProvisioning\DefineAcademicProgramDTO; |
||||
|
use App\Domains\Admission\Models\AcademicProgram; |
||||
|
|
||||
|
class DefineAcademicProgram |
||||
|
{ |
||||
|
public function execute(DefineAcademicProgramDTO $dto): void |
||||
|
{ |
||||
|
AcademicProgram::create([ |
||||
|
'name' => $dto->name, |
||||
|
'code' => $dto->code, |
||||
|
'status' => $dto->status, |
||||
|
]); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Admission\DTOs\AdmissionPricing; |
||||
|
|
||||
|
readonly class AdmissionFeeRatesDTO |
||||
|
{ |
||||
|
public function __construct( |
||||
|
public int $termId, |
||||
|
public int $academicProgramId, |
||||
|
public int $admissionTrackId, |
||||
|
public int $feeTypeId, |
||||
|
public float $amount, |
||||
|
) {} |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Admission\DTOs\AdmissionPricing; |
||||
|
|
||||
|
readonly class FeeTypeDTO |
||||
|
{ |
||||
|
public function __construct( |
||||
|
public string $name, |
||||
|
public string $billingCycle |
||||
|
) {} |
||||
|
} |
||||
@ -0,0 +1,15 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Admission\DTOs\IntakeScheduling; |
||||
|
|
||||
|
use Carbon\CarbonImmutable; |
||||
|
|
||||
|
readonly class AdjustAdmissionScheduleDurationDTO |
||||
|
{ |
||||
|
public function __construct( |
||||
|
public CarbonImmutable $startData, |
||||
|
public CarbonImmutable $endData, |
||||
|
public CarbonImmutable $reRegisterStartData, |
||||
|
public CarbonImmutable $reRegisterEndData, |
||||
|
) {} |
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Admission\DTOs\IntakeScheduling; |
||||
|
|
||||
|
use App\Domains\Admission\Enums\AdmissionStatus; |
||||
|
use Carbon\CarbonImmutable; |
||||
|
|
||||
|
readonly class PublishAdmissionScheduleDTO |
||||
|
{ |
||||
|
public function __construct( |
||||
|
public CarbonImmutable $startData, |
||||
|
public CarbonImmutable $endData, |
||||
|
public CarbonImmutable $reRegisterStartData, |
||||
|
public CarbonImmutable $reRegisterEndData, |
||||
|
public AdmissionStatus $status, |
||||
|
public int $termId, |
||||
|
public int $admissionTrackId |
||||
|
) {} |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Admission\DTOs\IntakeSourcing; |
||||
|
|
||||
|
use App\Domains\System\Enums\LifecycleStatus; |
||||
|
|
||||
|
readonly class InitializeAdmissionTrackDTO |
||||
|
{ |
||||
|
public function __construct( |
||||
|
public string $name, |
||||
|
public LifecycleStatus $status, |
||||
|
) {} |
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Admission\DTOs\StudyModeProvisioning; |
||||
|
|
||||
|
use App\Domains\System\Enums\LifecycleStatus; |
||||
|
|
||||
|
readonly class DefineAcademicProgramDTO |
||||
|
{ |
||||
|
public function __construct( |
||||
|
public string $name, |
||||
|
public string $code, |
||||
|
public LifecycleStatus $status, |
||||
|
) {} |
||||
|
} |
||||
@ -0,0 +1,27 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Admission\Enums; |
||||
|
|
||||
|
use App\Domains\System\Traits\Enum\HasPredicateMethod; |
||||
|
use App\UI\Enums\Concerns\InteractsWithLabels; |
||||
|
use App\UI\Enums\Contracts\HasLabel; |
||||
|
use App\UI\Enums\Contracts\HasUiBadge; |
||||
|
|
||||
|
enum AdmissionStatus: string implements HasLabel, HasUiBadge |
||||
|
{ |
||||
|
use HasPredicateMethod; |
||||
|
use InteractsWithLabels; |
||||
|
|
||||
|
case PUBLISHED = 'published'; |
||||
|
case DRAFT = 'draft'; |
||||
|
case ARCHIVED = 'archived'; |
||||
|
|
||||
|
public function variant(): string |
||||
|
{ |
||||
|
return match ($this) { |
||||
|
self::PUBLISHED => 'success', |
||||
|
self::DRAFT => 'warning', |
||||
|
self::ARCHIVED => 'danger', |
||||
|
}; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Admission\Enums; |
||||
|
|
||||
|
use App\Domains\System\Traits\Enum\HasPredicateMethod; |
||||
|
use App\UI\Enums\Concerns\InteractsWithLabels; |
||||
|
use App\UI\Enums\Contracts\HasLabel; |
||||
|
|
||||
|
enum BillingCycle: string implements HasLabel |
||||
|
{ |
||||
|
use HasPredicateMethod; |
||||
|
use InteractsWithLabels; |
||||
|
|
||||
|
case ONCE = 'once'; |
||||
|
case MONTHLY = 'monthly'; |
||||
|
case SEMESTER = 'semester'; |
||||
|
case ANNUAL = 'annual'; |
||||
|
} |
||||
@ -0,0 +1,35 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Admission\Models; |
||||
|
|
||||
|
use App\Domains\Admission\Policies\AcademicProgramPolicy; |
||||
|
use App\Domains\System\Enums\LifecycleStatus; |
||||
|
use Database\Factories\Academic\AcademicProgramFactory; |
||||
|
use Illuminate\Database\Eloquent\Attributes\Fillable; |
||||
|
use Illuminate\Database\Eloquent\Attributes\UsePolicy; |
||||
|
use Illuminate\Database\Eloquent\Concerns\HasUlids; |
||||
|
use Illuminate\Database\Eloquent\Factories\Factory; |
||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory; |
||||
|
use Illuminate\Database\Eloquent\Model; |
||||
|
|
||||
|
#[Fillable(['code', 'name', 'status'])] |
||||
|
#[UsePolicy(AcademicProgramPolicy::class)] |
||||
|
class AcademicProgram extends Model |
||||
|
{ |
||||
|
use HasFactory; |
||||
|
use HasUlids; |
||||
|
|
||||
|
protected $casts = [ |
||||
|
'status' => LifecycleStatus::class, |
||||
|
]; |
||||
|
|
||||
|
protected static function newFactory(): Factory |
||||
|
{ |
||||
|
return AcademicProgramFactory::new(); |
||||
|
} |
||||
|
|
||||
|
public function uniqueIds(): array |
||||
|
{ |
||||
|
return ['ulid']; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,53 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Admission\Models; |
||||
|
|
||||
|
use App\Domains\Admission\Policies\AdmissionSchedulePolicy; |
||||
|
use App\Domains\Admission\Enums\AdmissionStatus; |
||||
|
use Database\Factories\Admission\AdmissionScheduleFactory; |
||||
|
use Illuminate\Database\Eloquent\Attributes\Fillable; |
||||
|
use Illuminate\Database\Eloquent\Attributes\UsePolicy; |
||||
|
use Illuminate\Database\Eloquent\Concerns\HasUlids; |
||||
|
use Illuminate\Database\Eloquent\Factories\Factory; |
||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory; |
||||
|
use Illuminate\Database\Eloquent\Model; |
||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo; |
||||
|
|
||||
|
#[Fillable([ |
||||
|
'date_start', |
||||
|
'date_end', |
||||
|
're_registration_date_start', |
||||
|
're_registration_date_end', |
||||
|
'admission_track_id', |
||||
|
'status', |
||||
|
'term_id', |
||||
|
])] |
||||
|
#[UsePolicy(AdmissionSchedulePolicy::class)] |
||||
|
class AdmissionSchedule extends Model |
||||
|
{ |
||||
|
use HasFactory; |
||||
|
use HasUlids; |
||||
|
|
||||
|
protected $casts = [ |
||||
|
'date_start' => 'date', |
||||
|
'date_end' => 'date', |
||||
|
're_registration_date_start' => 'date', |
||||
|
're_registration_date_end' => 'date', |
||||
|
'status' => AdmissionStatus::class, |
||||
|
]; |
||||
|
|
||||
|
public function uniqueIds(): array |
||||
|
{ |
||||
|
return ['ulid']; |
||||
|
} |
||||
|
|
||||
|
protected static function newFactory(): Factory |
||||
|
{ |
||||
|
return AdmissionScheduleFactory::new(); |
||||
|
} |
||||
|
|
||||
|
public function admissionTrack(): BelongsTo |
||||
|
{ |
||||
|
return $this->belongsTo(AdmissionTrack::class); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,42 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Admission\Models; |
||||
|
|
||||
|
use App\Domains\Admission\Policies\AdmissionTrackPolicy; |
||||
|
use App\Domains\System\Enums\LifecycleStatus; |
||||
|
use App\Domains\System\Traits\Model\HasSlugs; |
||||
|
use Database\Factories\Admission\AdmissionTrackFactory; |
||||
|
use Illuminate\Database\Eloquent\Attributes\Fillable; |
||||
|
use Illuminate\Database\Eloquent\Attributes\UsePolicy; |
||||
|
use Illuminate\Database\Eloquent\Concerns\HasUlids; |
||||
|
use Illuminate\Database\Eloquent\Factories\Factory; |
||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory; |
||||
|
use Illuminate\Database\Eloquent\Model; |
||||
|
|
||||
|
#[Fillable(['name', 'slug', 'status'])] |
||||
|
#[UsePolicy(AdmissionTrackPolicy::class)] |
||||
|
class AdmissionTrack extends Model |
||||
|
{ |
||||
|
use HasFactory; |
||||
|
use HasUlids; |
||||
|
use HasSlugs; |
||||
|
|
||||
|
protected $casts = [ |
||||
|
'status' => LifecycleStatus::class, |
||||
|
]; |
||||
|
|
||||
|
public function uniqueIds(): array |
||||
|
{ |
||||
|
return ['ulid']; |
||||
|
} |
||||
|
|
||||
|
protected static function newFactory(): Factory |
||||
|
{ |
||||
|
return AdmissionTrackFactory::new(); |
||||
|
} |
||||
|
|
||||
|
public function sluggable(): string |
||||
|
{ |
||||
|
return 'name'; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,52 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Admission\Models; |
||||
|
|
||||
|
use App\Domains\Admission\Policies\FeeRatePolicy; |
||||
|
use Database\Factories\Admission\FeeRateFactory; |
||||
|
use Illuminate\Database\Eloquent\Attributes\Fillable; |
||||
|
use Illuminate\Database\Eloquent\Attributes\UsePolicy; |
||||
|
use Illuminate\Database\Eloquent\Concerns\HasUlids; |
||||
|
use Illuminate\Database\Eloquent\Factories\Factory; |
||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory; |
||||
|
use Illuminate\Database\Eloquent\Model; |
||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo; |
||||
|
|
||||
|
#[Fillable([ |
||||
|
'admission_schedule_id', |
||||
|
'academic_program_id', |
||||
|
'study_program_id', |
||||
|
'fee_type_id', |
||||
|
'amount', |
||||
|
])] |
||||
|
#[UsePolicy(FeeRatePolicy::class)] |
||||
|
class FeeRate extends Model |
||||
|
{ |
||||
|
use HasFactory; |
||||
|
use HasUlids; |
||||
|
|
||||
|
public function uniqueIds(): array |
||||
|
{ |
||||
|
return ['ulid']; |
||||
|
} |
||||
|
|
||||
|
protected static function newFactory(): Factory |
||||
|
{ |
||||
|
return FeeRateFactory::new(); |
||||
|
} |
||||
|
|
||||
|
public function admissionSchedule(): BelongsTo |
||||
|
{ |
||||
|
return $this->belongsTo(AdmissionSchedule::class); |
||||
|
} |
||||
|
|
||||
|
public function academicProgram(): BelongsTo |
||||
|
{ |
||||
|
return $this->belongsTo(AcademicProgram::class); |
||||
|
} |
||||
|
|
||||
|
public function feeType(): BelongsTo |
||||
|
{ |
||||
|
return $this->belongsTo(FeeType::class); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,35 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Admission\Models; |
||||
|
|
||||
|
use App\Domains\Admission\Enums\BillingCycle; |
||||
|
use App\Domains\Admission\Policies\FeeTypePolicy; |
||||
|
use Database\Factories\Admission\FeeTypeFactory; |
||||
|
use Illuminate\Database\Eloquent\Attributes\Fillable; |
||||
|
use Illuminate\Database\Eloquent\Attributes\UsePolicy; |
||||
|
use Illuminate\Database\Eloquent\Concerns\HasUlids; |
||||
|
use Illuminate\Database\Eloquent\Factories\Factory; |
||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory; |
||||
|
use Illuminate\Database\Eloquent\Model; |
||||
|
|
||||
|
#[Fillable(['name', 'billing_cycle'])] |
||||
|
#[UsePolicy(FeeTypePolicy::class)] |
||||
|
class FeeType extends Model |
||||
|
{ |
||||
|
use HasFactory; |
||||
|
use HasUlids; |
||||
|
|
||||
|
protected $casts = [ |
||||
|
'billing_cycle' => BillingCycle::class, |
||||
|
]; |
||||
|
|
||||
|
public function uniqueIds(): array |
||||
|
{ |
||||
|
return ['ulid']; |
||||
|
} |
||||
|
|
||||
|
protected static function newFactory(): Factory |
||||
|
{ |
||||
|
return FeeTypeFactory::new(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,49 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Admission\Policies; |
||||
|
|
||||
|
use App\Domains\Admission\Models\AcademicProgram; |
||||
|
use App\Domains\Identity\Models\User; |
||||
|
|
||||
|
class AcademicProgramPolicy |
||||
|
{ |
||||
|
/** |
||||
|
* Determine whether the user can view any models. |
||||
|
*/ |
||||
|
public function viewAny(User $user): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('academic-program.viewAny'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can view the model. |
||||
|
*/ |
||||
|
public function view(User $user, AcademicProgram $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('academic-program.view'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can create models. |
||||
|
*/ |
||||
|
public function create(User $user): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('academic-program.create'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can update the model. |
||||
|
*/ |
||||
|
public function update(User $user, AcademicProgram $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('academic-program.update'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can delete the model. |
||||
|
*/ |
||||
|
public function delete(User $user, AcademicProgram $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('academic-program.delete'); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,49 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Admission\Policies; |
||||
|
|
||||
|
use App\Domains\Admission\Models\AdmissionSchedule; |
||||
|
use App\Domains\Identity\Models\User; |
||||
|
|
||||
|
class AdmissionSchedulePolicy |
||||
|
{ |
||||
|
/** |
||||
|
* Determine whether the user can view any models. |
||||
|
*/ |
||||
|
public function viewAny(User $user): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('admission-schedule.viewAny'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can view the model. |
||||
|
*/ |
||||
|
public function view(User $user, AdmissionSchedule $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('admission-schedule.view'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can create models. |
||||
|
*/ |
||||
|
public function create(User $user): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('admission-schedule.create'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can update the model. |
||||
|
*/ |
||||
|
public function update(User $user, AdmissionSchedule $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('admission-schedule.update'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can delete the model. |
||||
|
*/ |
||||
|
public function delete(User $user, AdmissionSchedule $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('admission-schedule.delete'); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,49 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Admission\Policies; |
||||
|
|
||||
|
use App\Domains\Admission\Models\AdmissionTrack; |
||||
|
use App\Domains\Identity\Models\User; |
||||
|
|
||||
|
class AdmissionTrackPolicy |
||||
|
{ |
||||
|
/** |
||||
|
* Determine whether the user can view any models. |
||||
|
*/ |
||||
|
public function viewAny(User $user): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('admission-track.viewAny'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can view the model. |
||||
|
*/ |
||||
|
public function view(User $user, AdmissionTrack $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('admission-track.view'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can create models. |
||||
|
*/ |
||||
|
public function create(User $user): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('admission-track.create'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can update the model. |
||||
|
*/ |
||||
|
public function update(User $user, AdmissionTrack $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('admission-track.update'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can delete the model. |
||||
|
*/ |
||||
|
public function delete(User $user, AdmissionTrack $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('admission-track.delete'); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,49 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Admission\Policies; |
||||
|
|
||||
|
use App\Domains\Admission\Models\FeeRate; |
||||
|
use App\Domains\Identity\Models\User; |
||||
|
|
||||
|
class FeeRatePolicy |
||||
|
{ |
||||
|
/** |
||||
|
* Determine whether the user can view any models. |
||||
|
*/ |
||||
|
public function viewAny(User $user): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('fee-rate.viewAny'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can view the model. |
||||
|
*/ |
||||
|
public function view(User $user, FeeRate $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('fee-rate.view'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can create models. |
||||
|
*/ |
||||
|
public function create(User $user): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('fee-rate.create'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can update the model. |
||||
|
*/ |
||||
|
public function update(User $user, FeeRate $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('fee-rate.update'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can delete the model. |
||||
|
*/ |
||||
|
public function delete(User $user, FeeRate $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('fee-rate.delete'); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,49 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Admission\Policies; |
||||
|
|
||||
|
use App\Domains\Admission\Models\FeeType; |
||||
|
use App\Domains\Identity\Models\User; |
||||
|
|
||||
|
class FeeTypePolicy |
||||
|
{ |
||||
|
/** |
||||
|
* Determine whether the user can view any models. |
||||
|
*/ |
||||
|
public function viewAny(User $user): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('fee-type.viewAny'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can view the model. |
||||
|
*/ |
||||
|
public function view(User $user, FeeType $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('fee-type.view'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can create models. |
||||
|
*/ |
||||
|
public function create(User $user): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('fee-type.create'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can update the model. |
||||
|
*/ |
||||
|
public function update(User $user, FeeType $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('fee-type.update'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can delete the model. |
||||
|
*/ |
||||
|
public function delete(User $user, FeeType $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('fee-type.delete'); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Admission\Providers; |
||||
|
|
||||
|
use App\Domains\System\Traits\Provider\RegistersDomainEvents; |
||||
|
use Illuminate\Support\ServiceProvider; |
||||
|
|
||||
|
class AdmissionServiceProvider extends ServiceProvider |
||||
|
{ |
||||
|
use RegistersDomainEvents; |
||||
|
|
||||
|
protected array $listen = []; |
||||
|
|
||||
|
public function register(): void |
||||
|
{ |
||||
|
$this->app->register(RelationshipServiceProvider::class); |
||||
|
} |
||||
|
|
||||
|
public function boot(): void |
||||
|
{ |
||||
|
$this->registerEvents(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,31 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Admission\Providers; |
||||
|
|
||||
|
use Illuminate\Support\ServiceProvider; |
||||
|
|
||||
|
class RelationshipServiceProvider extends ServiceProvider |
||||
|
{ |
||||
|
/** |
||||
|
* Boot cross-domain runtime relationships. |
||||
|
* |
||||
|
* This provider is strictly dedicated to runtime, decoupled cross-domain |
||||
|
* relationship definitions. Use Model::resolveRelationUsing() here to wire |
||||
|
* explicit polymorphic or foreign-key macros between models that live in |
||||
|
* different domains — without introducing a hard compile-time dependency |
||||
|
* between those domains. |
||||
|
* |
||||
|
* Do NOT add route registrations, bindings, event listeners, or any other |
||||
|
* bootstrapping logic here. Keep this file focused on relationships only. |
||||
|
* |
||||
|
* Example: |
||||
|
* |
||||
|
* Order::resolveRelationUsing('customer', fn (Order $order) => |
||||
|
* $order->belongsTo(Customer::class, 'customer_id') |
||||
|
* ); |
||||
|
*/ |
||||
|
public function boot(): void |
||||
|
{ |
||||
|
// Register cross-domain relationships below. |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Channel\Actions\AppProvisioning; |
||||
|
|
||||
|
use App\Domains\Channel\Models\Client; |
||||
|
|
||||
|
class DeauthorizConsumerApp |
||||
|
{ |
||||
|
public function execute(Client $client): void |
||||
|
{ |
||||
|
// |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Channel\Actions\AppProvisioning; |
||||
|
|
||||
|
use App\Domains\Channel\Models\Client; |
||||
|
|
||||
|
class DeauthorizeConsumerApp |
||||
|
{ |
||||
|
public function execute(Client $client): void |
||||
|
{ |
||||
|
// |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Channel\Actions\AppProvisioning; |
||||
|
|
||||
|
use App\Domains\Channel\DTOs\AppProvisioning\ProvisionConsumerAppDTO; |
||||
|
use App\Domains\Channel\Models\Client; |
||||
|
|
||||
|
class ProvisionConsumerApp |
||||
|
{ |
||||
|
public function execute(ProvisionConsumerAppDTO $dto): void |
||||
|
{ |
||||
|
Client::create([ |
||||
|
'name' => $dto->name, |
||||
|
'code' => $dto->code, |
||||
|
'url' => $dto->url, |
||||
|
'secret' => encrypt(uuid_create()), |
||||
|
]); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Channel\Actions\AppProvisioning; |
||||
|
|
||||
|
use App\Domains\Channel\Models\Client; |
||||
|
|
||||
|
class RotateSecretKey |
||||
|
{ |
||||
|
public function execute(Client $client): void |
||||
|
{ |
||||
|
$key = encrypt(uuid_create()); |
||||
|
$client->update(['secret' => $key]); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,12 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Channel\DTOs\AppProvisioning; |
||||
|
|
||||
|
readonly class ProvisionConsumerAppDTO |
||||
|
{ |
||||
|
public function __construct( |
||||
|
public string $name, |
||||
|
public string $code, |
||||
|
public string $url, |
||||
|
) {} |
||||
|
} |
||||
@ -0,0 +1,34 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Channel\Models; |
||||
|
|
||||
|
use App\Domains\Channel\Policies\ClientPolicy; |
||||
|
use Database\Factories\Channel\ClientFactory; |
||||
|
use Illuminate\Database\Eloquent\Attributes\Fillable; |
||||
|
use Illuminate\Database\Eloquent\Attributes\UsePolicy; |
||||
|
use Illuminate\Database\Eloquent\Concerns\HasUlids; |
||||
|
use Illuminate\Database\Eloquent\Factories\Factory; |
||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory; |
||||
|
use Illuminate\Database\Eloquent\Model; |
||||
|
|
||||
|
#[Fillable(['name', 'url', 'code', 'secret'])] |
||||
|
#[UsePolicy(ClientPolicy::class)] |
||||
|
class Client extends Model |
||||
|
{ |
||||
|
use HasFactory; |
||||
|
use HasUlids; |
||||
|
|
||||
|
protected $casts = [ |
||||
|
'secret' => 'encrypted', |
||||
|
]; |
||||
|
|
||||
|
protected static function newFactory(): Factory |
||||
|
{ |
||||
|
return ClientFactory::new(); |
||||
|
} |
||||
|
|
||||
|
public function uniqueIds(): array |
||||
|
{ |
||||
|
return ['ulid']; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,49 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Channel\Policies; |
||||
|
|
||||
|
use App\Domains\Channel\Models\Client; |
||||
|
use App\Domains\Identity\Models\User; |
||||
|
|
||||
|
class ClientPolicy |
||||
|
{ |
||||
|
/** |
||||
|
* Determine whether the user can view any models. |
||||
|
*/ |
||||
|
public function viewAny(User $user): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('client.viewAny'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can view the model. |
||||
|
*/ |
||||
|
public function view(User $user, Client $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('client.view'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can create models. |
||||
|
*/ |
||||
|
public function create(User $user): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('client.create'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can update the model. |
||||
|
*/ |
||||
|
public function update(User $user, Client $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('client.update'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can delete the model. |
||||
|
*/ |
||||
|
public function delete(User $user, Client $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('client.delete'); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Channel\Providers; |
||||
|
|
||||
|
use App\Domains\System\Traits\Provider\RegistersDomainEvents; |
||||
|
use Illuminate\Support\ServiceProvider; |
||||
|
|
||||
|
class ChannelServiceProvider extends ServiceProvider |
||||
|
{ |
||||
|
use RegistersDomainEvents; |
||||
|
|
||||
|
protected array $listen = []; |
||||
|
|
||||
|
public function register(): void |
||||
|
{ |
||||
|
$this->app->register(RelationshipServiceProvider::class); |
||||
|
} |
||||
|
|
||||
|
public function boot(): void |
||||
|
{ |
||||
|
$this->registerEvents(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,51 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Channel\Providers; |
||||
|
|
||||
|
use App\Domains\Channel\Models\Client; |
||||
|
use App\Domains\Finance\Models\Invoice; |
||||
|
use App\Domains\Finance\Models\ProductMapping; |
||||
|
use Illuminate\Support\ServiceProvider; |
||||
|
|
||||
|
class RelationshipServiceProvider extends ServiceProvider |
||||
|
{ |
||||
|
/** |
||||
|
* Boot cross-domain runtime relationships. |
||||
|
* |
||||
|
* This provider is strictly dedicated to runtime, decoupled cross-domain |
||||
|
* relationship definitions. Use Model::resolveRelationUsing() here to wire |
||||
|
* explicit polymorphic or foreign-key macros between models that live in |
||||
|
* different domains — without introducing a hard compile-time dependency |
||||
|
* between those domains. |
||||
|
* |
||||
|
* Do NOT add route registrations, bindings, event listeners, or any other |
||||
|
* bootstrapping logic here. Keep this file focused on relationships only. |
||||
|
* |
||||
|
* Example: |
||||
|
* |
||||
|
* Order::resolveRelationUsing('customer', fn (Order $order) => |
||||
|
* $order->belongsTo(Customer::class, 'customer_id') |
||||
|
* ); |
||||
|
*/ |
||||
|
public function boot(): void |
||||
|
{ |
||||
|
// Register cross-domain relationships below. |
||||
|
Client::resolveRelationUsing('transaction', fn (Client $client) => $client->hasMany( |
||||
|
related: Invoice::class, |
||||
|
foreignKey: 'client_id' |
||||
|
)); |
||||
|
Invoice::resolveRelationUsing('client', fn (Invoice $transaction) => $transaction->belongsTo( |
||||
|
related: Client::class, |
||||
|
foreignKey: 'client_id' |
||||
|
)); |
||||
|
|
||||
|
Client::resolveRelationUsing('product_mapping', fn (Client $client) => $client->hasMany( |
||||
|
related: ProductMapping::class, |
||||
|
foreignKey: 'client_id' |
||||
|
)); |
||||
|
ProductMapping::resolveRelationUsing('client', fn (ProductMapping $productMapping) => $productMapping->belongsTo( |
||||
|
related: Client::class, |
||||
|
foreignKey: 'client_id' |
||||
|
)); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\Actions\DisbursementProcessing; |
||||
|
|
||||
|
class DisburseFunds |
||||
|
{ |
||||
|
public function execute(): void |
||||
|
{ |
||||
|
// |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\Actions\DisbursementProcessing; |
||||
|
|
||||
|
class RecordVendorBill |
||||
|
{ |
||||
|
public function execute(): void |
||||
|
{ |
||||
|
// |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\Actions\LedgerConfiguration; |
||||
|
|
||||
|
use App\Domains\Finance\DTOs\LedgerConfiguration\AdjustAccountClassificationDTO; |
||||
|
use App\Domains\Finance\Models\ChartOfAccount; |
||||
|
|
||||
|
class AdjustAccountClassification |
||||
|
{ |
||||
|
public function execute(ChartOfAccount $coa, AdjustAccountClassificationDTO $dto): void |
||||
|
{ |
||||
|
$coa->update([ |
||||
|
'code' => $dto->code, |
||||
|
'name' => $dto->name, |
||||
|
'classification' => $dto->classification, |
||||
|
'parent_id' => $dto->parentId, |
||||
|
]); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,20 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\Actions\LedgerConfiguration; |
||||
|
|
||||
|
use App\Domains\Finance\DTOs\LedgerConfiguration\RegisterChartOfAccountDTO; |
||||
|
use App\Domains\Finance\Models\ChartOfAccount; |
||||
|
|
||||
|
class RegisterChartOfAccount |
||||
|
{ |
||||
|
public function execute(RegisterChartOfAccountDTO $dto): void |
||||
|
{ |
||||
|
ChartOfAccount::create([ |
||||
|
'code' => $dto->code, |
||||
|
'name' => $dto->name, |
||||
|
'classification' => $dto->classification, |
||||
|
'status' => $dto->status, |
||||
|
'parent_id' => $dto->parentId, |
||||
|
]); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,16 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\Actions\LedgerConfiguration; |
||||
|
|
||||
|
use App\Domains\Finance\Models\ChartOfAccount; |
||||
|
use App\Domains\System\Enums\LifecycleStatus; |
||||
|
|
||||
|
class SuspendAccountPostings |
||||
|
{ |
||||
|
public function execute(ChartOfAccount $coa): void |
||||
|
{ |
||||
|
$coa->update([ |
||||
|
'status' => LifecycleStatus::ARCHIVED, |
||||
|
]); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\Actions\PaymentProcessing; |
||||
|
|
||||
|
class InitializeInvoice |
||||
|
{ |
||||
|
public function execute(): void |
||||
|
{ |
||||
|
// |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\Actions\PaymentProcessing; |
||||
|
|
||||
|
class ProcessIncomingPaymentWebhook |
||||
|
{ |
||||
|
public function execute(): void |
||||
|
{ |
||||
|
// |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\Actions\ProductConfiguration; |
||||
|
|
||||
|
class CreateProductMapping |
||||
|
{ |
||||
|
public function execute(): void |
||||
|
{ |
||||
|
// |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\Actions\ProductConfiguration; |
||||
|
|
||||
|
class RegisterProductMapping |
||||
|
{ |
||||
|
public function execute(): void |
||||
|
{ |
||||
|
// |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,37 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\Casts; |
||||
|
|
||||
|
use App\Domains\Finance\Support\ValueObjects\Money; |
||||
|
use Illuminate\Contracts\Database\Eloquent\CastsAttributes; |
||||
|
use Illuminate\Database\Eloquent\Model; |
||||
|
use InvalidArgumentException; |
||||
|
|
||||
|
class MoneyCurrency implements CastsAttributes |
||||
|
{ |
||||
|
public function get(Model $model, string $key, mixed $value, array $attributes): ?Money |
||||
|
{ |
||||
|
if (is_null($value)) { |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
return new Money((int) $value); |
||||
|
} |
||||
|
|
||||
|
public function set(Model $model, string $key, mixed $value, array $attributes): ?float |
||||
|
{ |
||||
|
if (is_null($value)) { |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
if ($value instanceof Money) { |
||||
|
return $value->amount; |
||||
|
} |
||||
|
|
||||
|
if (is_numeric($value)) { |
||||
|
return (float) $value; |
||||
|
} |
||||
|
|
||||
|
throw new InvalidArgumentException("The {$key} attribute must be an float or an instance of Money."); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\DTOs\DisbursementProcessing; |
||||
|
|
||||
|
readonly class DisburseFundsDTO |
||||
|
{ |
||||
|
public function __construct( |
||||
|
// |
||||
|
) {} |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\DTOs\DisbursementProcessing; |
||||
|
|
||||
|
readonly class VendorBillDTO |
||||
|
{ |
||||
|
public function __construct( |
||||
|
// |
||||
|
) {} |
||||
|
} |
||||
@ -0,0 +1,15 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\DTOs\LedgerConfiguration; |
||||
|
|
||||
|
use App\Domains\Finance\Enums\AccountClassification; |
||||
|
|
||||
|
readonly class AdjustAccountClassificationDTO |
||||
|
{ |
||||
|
public function __construct( |
||||
|
public string $code, |
||||
|
public string $name, |
||||
|
public AccountClassification $classification, |
||||
|
public ?int $parentId, |
||||
|
) {} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\DTOs\LedgerConfiguration; |
||||
|
|
||||
|
use App\Domains\Finance\Enums\AccountClassification; |
||||
|
use App\Domains\System\Enums\LifecycleStatus; |
||||
|
|
||||
|
readonly class RegisterChartOfAccountDTO |
||||
|
{ |
||||
|
public function __construct( |
||||
|
public string $code, |
||||
|
public string $name, |
||||
|
public AccountClassification $classification, |
||||
|
public LifecycleStatus $status, |
||||
|
public ?int $parentId, |
||||
|
) {} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\DTOs\PaymentProcessing; |
||||
|
|
||||
|
use Carbon\CarbonImmutable; |
||||
|
|
||||
|
readonly class BankWebhookPayloadDTO |
||||
|
{ |
||||
|
public function __construct( |
||||
|
public int $virtualAccount, |
||||
|
public string $bankRefId, |
||||
|
public CarbonImmutable $validUntil, |
||||
|
public float $amount, |
||||
|
public string $status, |
||||
|
public string $transactionId |
||||
|
) {} |
||||
|
} |
||||
@ -0,0 +1,15 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\DTOs\PaymentProcessing; |
||||
|
|
||||
|
readonly class IssueInvoiceDTO |
||||
|
{ |
||||
|
public function __construct( |
||||
|
public string $name, |
||||
|
public string $clientRefId, |
||||
|
public string $detail, |
||||
|
public string $type, |
||||
|
public string $status, |
||||
|
public string $clientId |
||||
|
) {} |
||||
|
} |
||||
@ -0,0 +1,12 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\DTOs\ProductConfiguration; |
||||
|
|
||||
|
readonly class RegisterProductMappingDTO |
||||
|
{ |
||||
|
public function __construct( |
||||
|
public string $name, |
||||
|
public string $code, |
||||
|
public int $coaId |
||||
|
) {} |
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\Enums; |
||||
|
|
||||
|
use App\Domains\System\Traits\Enum\HasPredicateMethod; |
||||
|
use App\UI\Enums\Concerns\InteractsWithLabels; |
||||
|
use App\UI\Enums\Contracts\HasLabel; |
||||
|
|
||||
|
enum AccountClassification: string implements HasLabel |
||||
|
{ |
||||
|
use HasPredicateMethod; |
||||
|
use InteractsWithLabels; |
||||
|
|
||||
|
case ASSET = 'asset'; |
||||
|
case LIABILITY = 'liability'; |
||||
|
case EQUITY = 'equity'; |
||||
|
case REVENUE = 'revenue'; |
||||
|
case EXPENSE = 'expense'; |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\Enums; |
||||
|
|
||||
|
use App\Domains\System\Traits\Enum\HasPredicateMethod; |
||||
|
use App\UI\Enums\Concerns\InteractsWithLabels; |
||||
|
use App\UI\Enums\Contracts\HasLabel; |
||||
|
|
||||
|
enum InvoiceStatus: string implements HasLabel |
||||
|
{ |
||||
|
use HasPredicateMethod; |
||||
|
use InteractsWithLabels; |
||||
|
|
||||
|
case PAID = 'paid'; |
||||
|
case PENDING = 'pending'; |
||||
|
case PARTIALLY_PAID = 'partially_paid'; |
||||
|
case OVERDUE = 'overdue'; |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\Enums; |
||||
|
|
||||
|
use App\Domains\System\Traits\Enum\HasPredicateMethod; |
||||
|
use App\UI\Enums\Concerns\InteractsWithLabels; |
||||
|
use App\UI\Enums\Contracts\HasLabel; |
||||
|
|
||||
|
enum InvoiceType: string implements HasLabel |
||||
|
{ |
||||
|
use HasPredicateMethod; |
||||
|
use InteractsWithLabels; |
||||
|
|
||||
|
case CUSTOMER_INVOICE = 'customer_invoice'; |
||||
|
case VENDOR_BILL = 'vendor_bill'; |
||||
|
case CREDIT_NOTE = 'credit_note'; |
||||
|
} |
||||
@ -0,0 +1,16 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\Enums; |
||||
|
|
||||
|
use App\Domains\System\Traits\Enum\HasPredicateMethod; |
||||
|
use App\UI\Enums\Concerns\InteractsWithLabels; |
||||
|
use App\UI\Enums\Contracts\HasLabel; |
||||
|
|
||||
|
enum PaymentDirection: string implements HasLabel |
||||
|
{ |
||||
|
use HasPredicateMethod; |
||||
|
use InteractsWithLabels; |
||||
|
|
||||
|
case RECEIPT = 'receipt'; |
||||
|
case DISBURSEMENT = 'disbursement'; |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\Enums; |
||||
|
|
||||
|
use App\Domains\System\Traits\Enum\HasPredicateMethod; |
||||
|
use App\UI\Enums\Concerns\InteractsWithLabels; |
||||
|
use App\UI\Enums\Contracts\HasLabel; |
||||
|
|
||||
|
enum PaymentStatus: string implements HasLabel |
||||
|
{ |
||||
|
use HasPredicateMethod; |
||||
|
use InteractsWithLabels; |
||||
|
|
||||
|
case PENDING = 'pending'; |
||||
|
case SUCCESS = 'success'; |
||||
|
case FAILED = 'failed'; |
||||
|
case EXPIRED = 'expired'; |
||||
|
} |
||||
@ -0,0 +1,43 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\Models; |
||||
|
|
||||
|
use App\Domains\Finance\Enums\AccountClassification; |
||||
|
use App\Domains\Finance\Policies\ChartOfAccountPolicy; |
||||
|
use App\Domains\System\Enums\LifecycleStatus; |
||||
|
use Database\Factories\Finance\ChartOfAccountFactory; |
||||
|
use Illuminate\Database\Eloquent\Attributes\Fillable; |
||||
|
use Illuminate\Database\Eloquent\Attributes\UsePolicy; |
||||
|
use Illuminate\Database\Eloquent\Concerns\HasUlids; |
||||
|
use Illuminate\Database\Eloquent\Factories\Factory; |
||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory; |
||||
|
use Illuminate\Database\Eloquent\Model; |
||||
|
|
||||
|
#[Fillable([ |
||||
|
'code', |
||||
|
'name', |
||||
|
'classification', |
||||
|
'status', |
||||
|
'parent_id', |
||||
|
])] |
||||
|
#[UsePolicy(ChartOfAccountPolicy::class)] |
||||
|
class ChartOfAccount extends Model |
||||
|
{ |
||||
|
use HasFactory; |
||||
|
use HasUlids; |
||||
|
|
||||
|
protected $casts = [ |
||||
|
'classification' => AccountClassification::class, |
||||
|
'status' => LifecycleStatus::class, |
||||
|
]; |
||||
|
|
||||
|
public function uniqueIds(): array |
||||
|
{ |
||||
|
return ['ulid']; |
||||
|
} |
||||
|
|
||||
|
protected static function newFactory(): Factory |
||||
|
{ |
||||
|
return ChartOfAccountFactory::new(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,60 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\Models; |
||||
|
|
||||
|
use App\Domains\Finance\Casts\MoneyCurrency; |
||||
|
use App\Domains\Finance\Enums\InvoiceStatus; |
||||
|
use App\Domains\Finance\Enums\InvoiceType; |
||||
|
use App\Domains\Finance\Policies\InvoicePolicy; |
||||
|
use Database\Factories\Finance\InvoiceFactory; |
||||
|
use Illuminate\Database\Eloquent\Attributes\Fillable; |
||||
|
use Illuminate\Database\Eloquent\Attributes\UsePolicy; |
||||
|
use Illuminate\Database\Eloquent\Concerns\HasUlids; |
||||
|
use Illuminate\Database\Eloquent\Factories\Factory; |
||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory; |
||||
|
use Illuminate\Database\Eloquent\Model; |
||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo; |
||||
|
use Illuminate\Database\Eloquent\Relations\HasMany; |
||||
|
|
||||
|
#[Fillable([ |
||||
|
'name', |
||||
|
'detail', |
||||
|
'client_ref_id', |
||||
|
'type', |
||||
|
'amount', |
||||
|
'status', |
||||
|
'client_id', |
||||
|
'chart_of_account_id', |
||||
|
])] |
||||
|
#[UsePolicy(InvoicePolicy::class)] |
||||
|
class Invoice extends Model |
||||
|
{ |
||||
|
use HasFactory; |
||||
|
use HasUlids; |
||||
|
|
||||
|
protected $casts = [ |
||||
|
'amount' => MoneyCurrency::class, |
||||
|
'type' => InvoiceType::class, |
||||
|
'status' => InvoiceStatus::class, |
||||
|
]; |
||||
|
|
||||
|
public function uniqueIds(): array |
||||
|
{ |
||||
|
return ['ulid']; |
||||
|
} |
||||
|
|
||||
|
protected static function newFactory(): Factory |
||||
|
{ |
||||
|
return InvoiceFactory::new(); |
||||
|
} |
||||
|
|
||||
|
public function chartOfAccount(): BelongsTo |
||||
|
{ |
||||
|
return $this->belongsTo(ChartOfAccount::class); |
||||
|
} |
||||
|
|
||||
|
public function payments(): HasMany |
||||
|
{ |
||||
|
return $this->hasMany(Payment::class); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,42 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\Models; |
||||
|
|
||||
|
use App\Domains\Finance\Casts\MoneyCurrency; |
||||
|
use App\Domains\Finance\Enums\InvoiceStatus; |
||||
|
use App\Domains\Finance\Policies\InvoiceReportPolicy; |
||||
|
use BadMethodCallException; |
||||
|
use Illuminate\Database\Eloquent\Attributes\Fillable; |
||||
|
use Illuminate\Database\Eloquent\Attributes\UsePolicy; |
||||
|
use Illuminate\Database\Eloquent\Model; |
||||
|
|
||||
|
#[Fillable([ |
||||
|
'invoice_id', |
||||
|
'invoice_name', |
||||
|
'customer_id', |
||||
|
'customer_name', |
||||
|
'amount', |
||||
|
'paid_amount', |
||||
|
'issued_at', |
||||
|
'paid_at', |
||||
|
'status', |
||||
|
])] |
||||
|
#[UsePolicy(InvoiceReportPolicy::class)] |
||||
|
class InvoiceReport extends Model |
||||
|
{ |
||||
|
public static function boot(): void |
||||
|
{ |
||||
|
self::boot(); |
||||
|
static::creating(fn (InvoiceReport $invoiceReport) => throw new BadMethodCallException('Cannot create invoice report from here, use event instead.')); |
||||
|
static::deleting(fn (InvoiceReport $invoiceReport) => throw new BadMethodCallException('Cannot delete invoice report.')); |
||||
|
static::updating(fn (InvoiceReport $invoiceReport) => throw new BadMethodCallException('Cannot update invoice report.')); |
||||
|
} |
||||
|
|
||||
|
protected $casts = [ |
||||
|
'amount' => MoneyCurrency::class, |
||||
|
'paid_amount' => MoneyCurrency::class, |
||||
|
'issued_at' => 'datetime', |
||||
|
'paid_at' => 'datetime', |
||||
|
'status' => InvoiceStatus::class, |
||||
|
]; |
||||
|
} |
||||
@ -0,0 +1,54 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\Models; |
||||
|
|
||||
|
use App\Domains\Finance\Casts\MoneyCurrency; |
||||
|
use App\Domains\Finance\Enums\PaymentDirection; |
||||
|
use App\Domains\Finance\Enums\PaymentStatus; |
||||
|
use App\Domains\Finance\Policies\PaymentPolicy; |
||||
|
use Database\Factories\Finance\PaymentFactory; |
||||
|
use Illuminate\Database\Eloquent\Attributes\Fillable; |
||||
|
use Illuminate\Database\Eloquent\Attributes\UsePolicy; |
||||
|
use Illuminate\Database\Eloquent\Concerns\HasUlids; |
||||
|
use Illuminate\Database\Eloquent\Factories\Factory; |
||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory; |
||||
|
use Illuminate\Database\Eloquent\Model; |
||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo; |
||||
|
|
||||
|
#[Fillable([ |
||||
|
'virtual_account', |
||||
|
'bank_ref_id', |
||||
|
'amount', |
||||
|
'valid_until', |
||||
|
'direction', |
||||
|
'status', |
||||
|
'transaction_id', |
||||
|
])] |
||||
|
#[UsePolicy(PaymentPolicy::class)] |
||||
|
class Payment extends Model |
||||
|
{ |
||||
|
use HasFactory; |
||||
|
use HasUlids; |
||||
|
|
||||
|
protected $casts = [ |
||||
|
'amount' => MoneyCurrency::class, |
||||
|
'valid_until' => 'datetime_immutable', |
||||
|
'direction' => PaymentDirection::class, |
||||
|
'status' => PaymentStatus::class, |
||||
|
]; |
||||
|
|
||||
|
public function uniqueIds(): array |
||||
|
{ |
||||
|
return ['ulid']; |
||||
|
} |
||||
|
|
||||
|
protected static function newFactory(): Factory |
||||
|
{ |
||||
|
return PaymentFactory::new(); |
||||
|
} |
||||
|
|
||||
|
public function transaction(): BelongsTo |
||||
|
{ |
||||
|
return $this->belongsTo(Invoice::class); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,24 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\Models; |
||||
|
|
||||
|
use App\Domains\Finance\Policies\ProductMappingPolicy; |
||||
|
use Illuminate\Database\Eloquent\Attributes\Fillable; |
||||
|
use Illuminate\Database\Eloquent\Attributes\UsePolicy; |
||||
|
use Illuminate\Database\Eloquent\Model; |
||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo; |
||||
|
|
||||
|
#[Fillable([ |
||||
|
'code', |
||||
|
'name', |
||||
|
'chart_of_account_id', |
||||
|
'client_id', |
||||
|
])] |
||||
|
#[UsePolicy(ProductMappingPolicy::class)] |
||||
|
class ProductMapping extends Model |
||||
|
{ |
||||
|
public function chartOfAccount(): BelongsTo |
||||
|
{ |
||||
|
return $this->belongsTo(ChartOfAccount::class); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,47 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\Models; |
||||
|
|
||||
|
use App\Domains\Finance\Casts\MoneyCurrency; |
||||
|
use App\Domains\Finance\Enums\InvoiceStatus; |
||||
|
use App\Domains\Finance\Policies\StudentInvoiceReportPolicy; |
||||
|
use BadMethodCallException; |
||||
|
use Illuminate\Database\Eloquent\Attributes\Fillable; |
||||
|
use Illuminate\Database\Eloquent\Attributes\UsePolicy; |
||||
|
use Illuminate\Database\Eloquent\Model; |
||||
|
|
||||
|
#[Fillable([ |
||||
|
'invoice_id', |
||||
|
'student_id', |
||||
|
'name', |
||||
|
'faculty_id', |
||||
|
'faculty_name', |
||||
|
'study_program_id', |
||||
|
'study_program_name', |
||||
|
'term_id', |
||||
|
'term_name', |
||||
|
'amount', |
||||
|
'paid_amount', |
||||
|
'issued_at', |
||||
|
'paid_at', |
||||
|
'status', |
||||
|
])] |
||||
|
#[UsePolicy(StudentInvoiceReportPolicy::class)] |
||||
|
class StudentInvoiceReport extends Model |
||||
|
{ |
||||
|
public static function boot(): void |
||||
|
{ |
||||
|
self::boot(); |
||||
|
static::creating(fn (InvoiceReport $invoiceReport) => throw new BadMethodCallException('Cannot create invoice report from here, use event instead.')); |
||||
|
static::deleting(fn (InvoiceReport $invoiceReport) => throw new BadMethodCallException('Cannot delete invoice report.')); |
||||
|
static::updating(fn (InvoiceReport $invoiceReport) => throw new BadMethodCallException('Cannot update invoice report.')); |
||||
|
} |
||||
|
|
||||
|
protected $casts = [ |
||||
|
'amount' => MoneyCurrency::class, |
||||
|
'paid_amount' => MoneyCurrency::class, |
||||
|
'issued_at' => 'datetime', |
||||
|
'paid_at' => 'datetime', |
||||
|
'status' => InvoiceStatus::class, |
||||
|
]; |
||||
|
} |
||||
@ -0,0 +1,49 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\Policies; |
||||
|
|
||||
|
use App\Domains\Finance\Models\ChartOfAccount; |
||||
|
use App\Domains\Identity\Models\User; |
||||
|
|
||||
|
class ChartOfAccountPolicy |
||||
|
{ |
||||
|
/** |
||||
|
* Determine whether the user can view any models. |
||||
|
*/ |
||||
|
public function viewAny(User $user): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('chart-of-account.viewAny'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can view the model. |
||||
|
*/ |
||||
|
public function view(User $user, ChartOfAccount $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('chart-of-account.view'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can create models. |
||||
|
*/ |
||||
|
public function create(User $user): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('chart-of-account.create'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can update the model. |
||||
|
*/ |
||||
|
public function update(User $user, ChartOfAccount $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('chart-of-account.update'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can delete the model. |
||||
|
*/ |
||||
|
public function delete(User $user, ChartOfAccount $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('chart-of-account.delete'); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,49 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\Policies; |
||||
|
|
||||
|
use App\Domains\Finance\Models\Invoice; |
||||
|
use App\Domains\Identity\Models\User; |
||||
|
|
||||
|
class InvoicePolicy |
||||
|
{ |
||||
|
/** |
||||
|
* Determine whether the user can view any models. |
||||
|
*/ |
||||
|
public function viewAny(User $user): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('invoice.viewAny'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can view the model. |
||||
|
*/ |
||||
|
public function view(User $user, Invoice $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('invoice.view'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can create models. |
||||
|
*/ |
||||
|
public function create(User $user): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('invoice.create'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can update the model. |
||||
|
*/ |
||||
|
public function update(User $user, Invoice $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('invoice.update'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can delete the model. |
||||
|
*/ |
||||
|
public function delete(User $user, Invoice $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('invoice.delete'); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,49 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\Policies; |
||||
|
|
||||
|
use App\Domains\Finance\Models\InvoiceReport; |
||||
|
use App\Domains\Identity\Models\User; |
||||
|
|
||||
|
class InvoiceReportPolicy |
||||
|
{ |
||||
|
/** |
||||
|
* Determine whether the user can view any models. |
||||
|
*/ |
||||
|
public function viewAny(User $user): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('invoice-report.viewAny'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can view the model. |
||||
|
*/ |
||||
|
public function view(User $user, InvoiceReport $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('invoice-report.view'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can create models. |
||||
|
*/ |
||||
|
public function create(User $user): bool |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can update the model. |
||||
|
*/ |
||||
|
public function update(User $user, InvoiceReport $model): bool |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can delete the model. |
||||
|
*/ |
||||
|
public function delete(User $user, InvoiceReport $model): bool |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,49 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\Policies; |
||||
|
|
||||
|
use App\Domains\Finance\Models\Payment; |
||||
|
use App\Domains\Identity\Models\User; |
||||
|
|
||||
|
class PaymentPolicy |
||||
|
{ |
||||
|
/** |
||||
|
* Determine whether the user can view any models. |
||||
|
*/ |
||||
|
public function viewAny(User $user): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('payment.viewAny'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can view the model. |
||||
|
*/ |
||||
|
public function view(User $user, Payment $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('payment.view'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can create models. |
||||
|
*/ |
||||
|
public function create(User $user): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('payment.create'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can update the model. |
||||
|
*/ |
||||
|
public function update(User $user, Payment $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('payment.update'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can delete the model. |
||||
|
*/ |
||||
|
public function delete(User $user, Payment $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('payment.delete'); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,49 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\Policies; |
||||
|
|
||||
|
use App\Domains\Finance\Models\ProductMapping; |
||||
|
use App\Domains\Identity\Models\User; |
||||
|
|
||||
|
class ProductMappingPolicy |
||||
|
{ |
||||
|
/** |
||||
|
* Determine whether the user can view any models. |
||||
|
*/ |
||||
|
public function viewAny(User $user): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('product-mapping.viewAny'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can view the model. |
||||
|
*/ |
||||
|
public function view(User $user, ProductMapping $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('product-mapping.view'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can create models. |
||||
|
*/ |
||||
|
public function create(User $user): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('product-mapping.create'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can update the model. |
||||
|
*/ |
||||
|
public function update(User $user, ProductMapping $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('product-mapping.update'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can delete the model. |
||||
|
*/ |
||||
|
public function delete(User $user, ProductMapping $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('product-mapping.delete'); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,49 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\Policies; |
||||
|
|
||||
|
use App\Domains\Finance\Models\StudentInvoiceReport; |
||||
|
use App\Domains\Identity\Models\User; |
||||
|
|
||||
|
class StudentInvoiceReportPolicy |
||||
|
{ |
||||
|
/** |
||||
|
* Determine whether the user can view any models. |
||||
|
*/ |
||||
|
public function viewAny(User $user): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('student-invoice-report.viewAny'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can view the model. |
||||
|
*/ |
||||
|
public function view(User $user, StudentInvoiceReport $model): bool |
||||
|
{ |
||||
|
return $user->hasPermissionTo('student-invoice-report.view'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can create models. |
||||
|
*/ |
||||
|
public function create(User $user): bool |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can update the model. |
||||
|
*/ |
||||
|
public function update(User $user, StudentInvoiceReport $model): bool |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine whether the user can delete the model. |
||||
|
*/ |
||||
|
public function delete(User $user, StudentInvoiceReport $model): bool |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\Providers; |
||||
|
|
||||
|
use App\Domains\System\Traits\Provider\RegistersDomainEvents; |
||||
|
use Illuminate\Support\ServiceProvider; |
||||
|
|
||||
|
class FinanceServiceProvider extends ServiceProvider |
||||
|
{ |
||||
|
use RegistersDomainEvents; |
||||
|
|
||||
|
protected array $listen = []; |
||||
|
|
||||
|
public function register(): void |
||||
|
{ |
||||
|
$this->app->register(RelationshipServiceProvider::class); |
||||
|
} |
||||
|
|
||||
|
public function boot(): void |
||||
|
{ |
||||
|
$this->registerEvents(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,31 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\Providers; |
||||
|
|
||||
|
use Illuminate\Support\ServiceProvider; |
||||
|
|
||||
|
class RelationshipServiceProvider extends ServiceProvider |
||||
|
{ |
||||
|
/** |
||||
|
* Boot cross-domain runtime relationships. |
||||
|
* |
||||
|
* This provider is strictly dedicated to runtime, decoupled cross-domain |
||||
|
* relationship definitions. Use Model::resolveRelationUsing() here to wire |
||||
|
* explicit polymorphic or foreign-key macros between models that live in |
||||
|
* different domains — without introducing a hard compile-time dependency |
||||
|
* between those domains. |
||||
|
* |
||||
|
* Do NOT add route registrations, bindings, event listeners, or any other |
||||
|
* bootstrapping logic here. Keep this file focused on relationships only. |
||||
|
* |
||||
|
* Example: |
||||
|
* |
||||
|
* Order::resolveRelationUsing('customer', fn (Order $order) => |
||||
|
* $order->belongsTo(Customer::class, 'customer_id') |
||||
|
* ); |
||||
|
*/ |
||||
|
public function boot(): void |
||||
|
{ |
||||
|
// Register cross-domain relationships below. |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,35 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Finance\Support\ValueObjects; |
||||
|
|
||||
|
use InvalidArgumentException; |
||||
|
use NumberFormatter; |
||||
|
use Stringable; |
||||
|
|
||||
|
class Money implements Stringable |
||||
|
{ |
||||
|
public function __construct(public float $amount) |
||||
|
{ |
||||
|
if ($this->amount < 0) { |
||||
|
throw new InvalidArgumentException('Money cannot be negative.'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Format the bytes into a human-readable string. |
||||
|
*/ |
||||
|
public function format(string $currency = 'IDR'): string |
||||
|
{ |
||||
|
$format = new NumberFormatter(app()->getLocale(), NumberFormatter::CURRENCY); |
||||
|
|
||||
|
return $format->formatCurrency($this->amount, $currency); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Automatically format when echoed in Blade (e.g., {{ $model->amount }}). |
||||
|
*/ |
||||
|
public function __toString(): string |
||||
|
{ |
||||
|
return $this->format(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,26 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Identity\Actions\AccessControl; |
||||
|
|
||||
|
use App\Domains\Identity\DTOs\AccessControl\CreateRoleDTO; |
||||
|
use App\Domains\Identity\Models\Role; |
||||
|
use Illuminate\Support\Facades\DB; |
||||
|
use Throwable; |
||||
|
|
||||
|
class DefineSystemRole |
||||
|
{ |
||||
|
/** |
||||
|
* @throws Throwable |
||||
|
*/ |
||||
|
public function execute(CreateRoleDTO $dto): bool |
||||
|
{ |
||||
|
return DB::transaction(function () use ($dto) { |
||||
|
$role = Role::create([ |
||||
|
'name' => $dto->name, |
||||
|
]); |
||||
|
$role->syncPermissions($dto->permissions); |
||||
|
|
||||
|
return true; |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,26 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Identity\Actions\AccessControl; |
||||
|
|
||||
|
use App\Domains\Identity\Enums\RoleType; |
||||
|
use App\Domains\Identity\Models\Role; |
||||
|
use Exception; |
||||
|
|
||||
|
use function in_array; |
||||
|
|
||||
|
class DeleteSystemRole |
||||
|
{ |
||||
|
/** |
||||
|
* @throws Exception |
||||
|
*/ |
||||
|
public function execute(Role $role): void |
||||
|
{ |
||||
|
if (in_array($role->name, [RoleType::ADMIN->value, RoleType::SYSTEM_ADMIN->value])) { |
||||
|
throw new Exception(__('domains/identity/messages.exceptions.cannot_remove_system_role')); |
||||
|
} |
||||
|
|
||||
|
if ($role->users()->exists()) { |
||||
|
throw new Exception(__('domains/identity/messages.exceptions.role_has_users')); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue