Browse Source
- Migrate localization keys and files to improved hierarchical paths. - Refactor relationship naming (e.g., `admission_schedules` to `admissionSchedules`) for consistency. - Enhance FeeType to support `code` attribute and update related actions, DTOs, and mappers. - Introduce `AdmissionFeeRateWasSetUp` event for better event-driven architecture. - Standardize migration scripts and nullable constraints for clarity and accuracy. - Update DataTables queries to use term filters with fallback to current term settings.master
155 changed files with 749 additions and 2625 deletions
@ -0,0 +1,18 @@ |
|||
<?php |
|||
|
|||
namespace App\Domains\Academic\Queries\Lookup; |
|||
|
|||
use App\Domains\Academic\Models\Faculty; |
|||
use Illuminate\Support\Collection; |
|||
|
|||
class FacultyLookup |
|||
{ |
|||
public static function fetch(): Collection |
|||
{ |
|||
return once(fn () => Faculty::query() |
|||
->select(['id', 'name']) |
|||
->latest() |
|||
->get() |
|||
->pluck('name', 'id')); |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
<?php |
|||
|
|||
namespace App\Domains\Academic\Queries\Lookup; |
|||
|
|||
use App\Domains\Academic\Models\Term; |
|||
use Illuminate\Support\Collection; |
|||
|
|||
class TermLookup |
|||
{ |
|||
public static function fetch($search = null): Collection |
|||
{ |
|||
return once(fn () => Term::query() |
|||
->select(['id', 'name']) |
|||
->when($search, fn ($query) => $query->where('name', 'like', "%{$search}%")) |
|||
->latest('date_start') |
|||
->pluck('name', 'name')); |
|||
} |
|||
} |
|||
@ -1,15 +0,0 @@ |
|||
<?php |
|||
|
|||
namespace App\Domains\Academic\Queries\Selection; |
|||
|
|||
use App\Domains\Academic\Models\Faculty; |
|||
use Illuminate\Support\Collection; |
|||
|
|||
class SelectFacultyQuery |
|||
{ |
|||
public static function fetch(): Collection |
|||
{ |
|||
return once(fn () => Faculty::all(['id', 'name']) |
|||
->pluck('name', 'id')); |
|||
} |
|||
} |
|||
@ -1,15 +0,0 @@ |
|||
<?php |
|||
|
|||
namespace App\Domains\Academic\Queries\Selection; |
|||
|
|||
use App\Domains\Academic\Models\Term; |
|||
use Illuminate\Support\Collection; |
|||
|
|||
class SelectTermQuery |
|||
{ |
|||
public static function fetch(): Collection |
|||
{ |
|||
return once(fn () => Term::all(['id', 'name']) |
|||
->pluck('name', 'id')); |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
<?php |
|||
|
|||
namespace App\Domains\Admission\Events\Pricing; |
|||
|
|||
use Illuminate\Foundation\Events\Dispatchable; |
|||
use Illuminate\Queue\SerializesModels; |
|||
|
|||
class AdmissionFeeRateWasSetUp |
|||
{ |
|||
use Dispatchable, SerializesModels; |
|||
|
|||
public function __construct( |
|||
public string $productName |
|||
) {} |
|||
} |
|||
@ -0,0 +1,108 @@ |
|||
<?php |
|||
|
|||
namespace App\Domains\Admission\Integration\Mappers; |
|||
|
|||
use App\Domains\Academic\Models\StudyProgram; |
|||
use App\Domains\Admission\Actions\AdmissionPricing\SetUpAdmissionFeeRates; |
|||
use App\Domains\Admission\DTOs\AdmissionPricing\AdmissionFeeRatesDTO; |
|||
use App\Domains\Admission\Models\AcademicProgram; |
|||
use App\Domains\Admission\Models\AdmissionSchedule; |
|||
use App\Domains\Admission\Models\FeeRate; |
|||
use App\Domains\Admission\Models\FeeType; |
|||
use Illuminate\Database\Eloquent\Model; |
|||
use App\Domains\System\Support\Integration\DataPayloadMapper; |
|||
|
|||
class FeeRateDataMapper implements DataPayloadMapper |
|||
{ |
|||
private static array $cache = []; |
|||
|
|||
public function __construct( |
|||
protected SetUpAdmissionFeeRates $setUpAdmissionFeeRates, |
|||
) |
|||
{ |
|||
// Inject required Domain and Cross-Domain Actions via constructor composition |
|||
} |
|||
|
|||
public function getLookupKey(): array |
|||
{ |
|||
// Return the unique string key used to identify existing records (e.g., 'email') |
|||
return ['admission_schedule_id', 'fee_type_id', 'academic_program_id']; |
|||
} |
|||
|
|||
public function transform(array $rawData): array |
|||
{ |
|||
if(!isset($rawData['jalur'])){ |
|||
dd($rawData); |
|||
} |
|||
// Normalize incoming data array formats into an internal domain-safe layout |
|||
return [ |
|||
'admission_schedule_id' => $this->resolveAdmissionScheduleId($rawData['jalur'], $rawData['angkatan']), |
|||
'academic_program_id' => $this->resolveAcademicProgramId($rawData['kode_Skuliah']), |
|||
'study_program_id' => $this->resolveStudyProgramId($rawData['kode_prodi']), |
|||
'fee_type_id'=> $this->resolveFeeTypeId($rawData['kode_Jtagihan']), |
|||
'amount' => $rawData['nominal_TRFtagihan'], |
|||
]; |
|||
} |
|||
|
|||
public function updateOrCreateDomainState(array $payload, ?Model $existingModel = null): void |
|||
{ |
|||
$this->setUpAdmissionFeeRates->execute(new AdmissionFeeRatesDTO( |
|||
academicProgramId: $payload['academic_program_id'], |
|||
admissionScheduleId: $payload['admission_schedule_id'], |
|||
studyProgramId: $payload['study_program_id'], |
|||
feeTypeId: $payload['fee_type_id'], |
|||
amount: $payload['amount'], |
|||
)); |
|||
} |
|||
|
|||
/** |
|||
* @return class-string |
|||
*/ |
|||
public function getModelClass(): string |
|||
{ |
|||
return FeeRate::class; |
|||
} |
|||
|
|||
public function resolveAdmissionScheduleId(string $admissionTrackSlug, int $yearStudy): int { |
|||
$key = hex2bin(md5("{$admissionTrackSlug}-{$yearStudy}") ); |
|||
if (!isset(self::$cache['admission_schedule'][$key])) { |
|||
self::$cache['admission_schedule'][$key] = AdmissionSchedule::query() |
|||
->whereHas( |
|||
'admissionTrack', |
|||
fn($builder) => $builder->where('slug', str($admissionTrackSlug)->slug()) |
|||
)->whereHas( |
|||
'term', |
|||
fn($builder) => $builder->where('year_study', $yearStudy) |
|||
)->first()?->id; |
|||
} |
|||
|
|||
return self::$cache['admission_schedule'][$key]; |
|||
} |
|||
|
|||
public function resolveStudyProgramId($code): int { |
|||
if (!isset(self::$cache['study_program'][$code])) { |
|||
self::$cache['study_program'][$code] = StudyProgram::where('code', $code)->first()?->id; |
|||
} |
|||
|
|||
return self::$cache['study_program'][$code]; |
|||
} |
|||
|
|||
public function resolveFeeTypeId(string $code): int { |
|||
$key = hex2bin(md5($code)); |
|||
if (!isset(self::$cache['fee_type'][$key])) { |
|||
self::$cache['fee_type'][$key] = FeeType::where('code', $code)->first()?->id; |
|||
} |
|||
|
|||
return self::$cache['fee_type'][$key]; |
|||
} |
|||
|
|||
|
|||
public function resolveAcademicProgramId(string $code): int { |
|||
$key = hex2bin(md5($code)); |
|||
if (!isset(self::$cache['academic_program'][$key])) { |
|||
self::$cache['academic_program'][$key] = AcademicProgram::where('code', $code)->first()?->id; |
|||
} |
|||
|
|||
return self::$cache['academic_program'][$key]; |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
<?php |
|||
|
|||
namespace App\Domains\Admission\Queries\Lookup; |
|||
|
|||
use App\Domains\Admission\Models\FeeType; |
|||
use Illuminate\Support\Collection; |
|||
|
|||
class FeeTypeLookup |
|||
{ |
|||
public static function fetch(): Collection |
|||
{ |
|||
return once(fn () => FeeType::query() |
|||
->select(['id', 'name']) |
|||
->latest() |
|||
->get() |
|||
->pluck('name', 'id')); |
|||
} |
|||
} |
|||
@ -1,13 +0,0 @@ |
|||
<?php |
|||
|
|||
namespace App\Domains\Admission\Queries\Selection; |
|||
|
|||
use Illuminate\Database\Eloquent\Collection; |
|||
|
|||
class SelectFeeTypeQuery |
|||
{ |
|||
public function fetch(): Collection |
|||
{ |
|||
return new Collection; |
|||
} |
|||
} |
|||
@ -1,11 +0,0 @@ |
|||
<?php |
|||
|
|||
namespace App\Domains\Finance\Actions\DisbursementProcessing; |
|||
|
|||
class DisburseFunds |
|||
{ |
|||
public function execute(): void |
|||
{ |
|||
// |
|||
} |
|||
} |
|||
@ -1,11 +0,0 @@ |
|||
<?php |
|||
|
|||
namespace App\Domains\Finance\Actions\DisbursementProcessing; |
|||
|
|||
class RecordVendorBill |
|||
{ |
|||
public function execute(): void |
|||
{ |
|||
// |
|||
} |
|||
} |
|||
@ -1,18 +0,0 @@ |
|||
<?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, |
|||
'classification' => $dto->classification, |
|||
'parent_id' => $dto->parentId, |
|||
]); |
|||
} |
|||
} |
|||
@ -1,20 +0,0 @@ |
|||
<?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, |
|||
]); |
|||
} |
|||
} |
|||
@ -1,16 +0,0 @@ |
|||
<?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::INACTIVE, |
|||
]); |
|||
} |
|||
} |
|||
@ -1,23 +0,0 @@ |
|||
<?php |
|||
|
|||
namespace App\Domains\Finance\Actions\PaymentProcessing; |
|||
|
|||
use App\Domains\Finance\DTOs\PaymentProcessing\IssueInvoiceDTO; |
|||
use App\Domains\Finance\Models\Invoice; |
|||
|
|||
class InitializeInvoice |
|||
{ |
|||
public function execute(IssueInvoiceDTO $dto): void |
|||
{ |
|||
Invoice::create([ |
|||
'name' => $dto->name, |
|||
'detail' => $dto->detail->toArray(), |
|||
'client_ref_id' => $dto->clientRefId, |
|||
'type' => $dto->type, |
|||
'amount' => $dto->amount, |
|||
'status' => $dto->status, |
|||
'client_id' => $dto->clientId, |
|||
'chart_of_account_id' => $dto->coaId, |
|||
]); |
|||
} |
|||
} |
|||
@ -1,11 +0,0 @@ |
|||
<?php |
|||
|
|||
namespace App\Domains\Finance\Actions\PaymentProcessing; |
|||
|
|||
class ProcessIncomingPaymentWebhook |
|||
{ |
|||
public function execute(): void |
|||
{ |
|||
// |
|||
} |
|||
} |
|||
@ -1,13 +0,0 @@ |
|||
<?php |
|||
|
|||
namespace App\Domains\Finance\Actions\ProductConfiguration; |
|||
|
|||
use App\Domains\Finance\Models\ProductMapping; |
|||
|
|||
class ModifyProductMapping |
|||
{ |
|||
public function execute(ProductMapping $productMapping, string|int $coaId): void |
|||
{ |
|||
$productMapping->update(['chart_of_account_id' => $coaId]); |
|||
} |
|||
} |
|||
@ -1,18 +0,0 @@ |
|||
<?php |
|||
|
|||
namespace App\Domains\Finance\Actions\ProductConfiguration; |
|||
|
|||
use App\Domains\Finance\DTOs\ProductConfiguration\RegisterProductMappingDTO; |
|||
use App\Domains\Finance\Models\ProductMapping; |
|||
|
|||
class RegisterProductMapping |
|||
{ |
|||
public function execute(RegisterProductMappingDTO $dto): void |
|||
{ |
|||
ProductMapping::create([ |
|||
'name' => $dto->name, |
|||
'code' => $dto->code, |
|||
'chart_of_account_id' => $dto->coaId, |
|||
]); |
|||
} |
|||
} |
|||
@ -1,10 +0,0 @@ |
|||
<?php |
|||
|
|||
namespace App\Domains\Finance\DTOs\DisbursementProcessing; |
|||
|
|||
readonly class DisburseFundsDTO |
|||
{ |
|||
public function __construct( |
|||
// |
|||
) {} |
|||
} |
|||
@ -1,10 +0,0 @@ |
|||
<?php |
|||
|
|||
namespace App\Domains\Finance\DTOs\DisbursementProcessing; |
|||
|
|||
readonly class VendorBillDTO |
|||
{ |
|||
public function __construct( |
|||
// |
|||
) {} |
|||
} |
|||
@ -1,14 +0,0 @@ |
|||
<?php |
|||
|
|||
namespace App\Domains\Finance\DTOs\LedgerConfiguration; |
|||
|
|||
use App\Domains\Finance\Enums\AccountClassification; |
|||
|
|||
readonly class AdjustAccountClassificationDTO |
|||
{ |
|||
public function __construct( |
|||
public string $code, |
|||
public AccountClassification $classification, |
|||
public ?int $parentId, |
|||
) {} |
|||
} |
|||
@ -1,17 +0,0 @@ |
|||
<?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, |
|||
) {} |
|||
} |
|||
@ -1,17 +0,0 @@ |
|||
<?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 |
|||
) {} |
|||
} |
|||
@ -1,10 +0,0 @@ |
|||
<?php |
|||
|
|||
namespace App\Domains\Finance\DTOs\PaymentProcessing\Detail; |
|||
|
|||
interface InvoiceDetailDTO |
|||
{ |
|||
public function toArray(): array; |
|||
|
|||
public static function fromArray(array $data): self; |
|||
} |
|||
@ -1,36 +0,0 @@ |
|||
<?php |
|||
|
|||
namespace App\Domains\Finance\DTOs\PaymentProcessing\Detail; |
|||
|
|||
class StudentInvoiceDetailDTO implements InvoiceDetailDTO |
|||
{ |
|||
public function __construct( |
|||
public string $studentId, |
|||
public string $studentName, |
|||
public string $faculty, |
|||
public string $studyProgram, |
|||
public string $term, |
|||
) {} |
|||
|
|||
public function toArray(): array |
|||
{ |
|||
return [ |
|||
'student_id' => $this->studentId, |
|||
'student_name' => $this->studentName, |
|||
'faculty' => $this->faculty, |
|||
'study_program' => $this->studyProgram, |
|||
'term' => $this->term, |
|||
]; |
|||
} |
|||
|
|||
public static function fromArray(array $data): self |
|||
{ |
|||
return new self( |
|||
studentId: $data['student_id'], |
|||
studentName: $data['student_name'], |
|||
faculty: $data['faculty'], |
|||
studyProgram: $data['study_program'], |
|||
term: $data['term'], |
|||
); |
|||
} |
|||
} |
|||
@ -1,21 +0,0 @@ |
|||
<?php |
|||
|
|||
namespace App\Domains\Finance\DTOs\PaymentProcessing; |
|||
|
|||
use App\Domains\Finance\DTOs\PaymentProcessing\Detail\InvoiceDetailDTO; |
|||
use App\Domains\Finance\Enums\InvoiceStatus; |
|||
use App\Domains\Finance\Enums\InvoiceType; |
|||
|
|||
readonly class IssueInvoiceDTO |
|||
{ |
|||
public function __construct( |
|||
public string $name, |
|||
public string $clientRefId, |
|||
public InvoiceDetailDTO $detail, |
|||
public InvoiceType $type, |
|||
public InvoiceStatus $status, |
|||
public int $amount, |
|||
public string $coaId, |
|||
public string $clientId |
|||
) {} |
|||
} |
|||
@ -1,10 +0,0 @@ |
|||
<?php |
|||
|
|||
namespace App\Domains\Finance\DTOs\ProductConfiguration; |
|||
|
|||
readonly class ModifyProductMappingDTO |
|||
{ |
|||
public function __construct( |
|||
// |
|||
) {} |
|||
} |
|||
@ -1,12 +0,0 @@ |
|||
<?php |
|||
|
|||
namespace App\Domains\Finance\DTOs\ProductConfiguration; |
|||
|
|||
readonly class RegisterProductMappingDTO |
|||
{ |
|||
public function __construct( |
|||
public string $name, |
|||
public string $code, |
|||
public int $coaId |
|||
) {} |
|||
} |
|||
@ -1,19 +0,0 @@ |
|||
<?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'; |
|||
} |
|||
@ -1,18 +0,0 @@ |
|||
<?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'; |
|||
} |
|||
@ -1,49 +0,0 @@ |
|||
<?php |
|||
|
|||
namespace App\Domains\Finance\Enums; |
|||
|
|||
use App\Domains\Finance\DTOs\PaymentProcessing\Detail\InvoiceDetailDTO; |
|||
use App\Domains\Finance\DTOs\PaymentProcessing\Detail\StudentInvoiceDetailDTO; |
|||
use App\Domains\Finance\Schemas\Invoice\StudentInvoiceSchema; |
|||
use App\Domains\Finance\Support\Schemas\InvoiceSchema; |
|||
use App\Domains\System\Traits\Enum\HasPredicateMethod; |
|||
use App\UI\Enums\Concerns\InteractsWithLabels; |
|||
use App\UI\Enums\Contracts\HasLabel; |
|||
use App\UI\Enums\Contracts\HasSchema; |
|||
use App\UI\Support\Schemas\InputSchemaField; |
|||
|
|||
enum InvoiceType: string implements HasLabel, HasSchema |
|||
{ |
|||
use HasPredicateMethod; |
|||
use InteractsWithLabels; |
|||
|
|||
case STUDENT_INVOICE = 'student_invoice'; |
|||
case VENDOR_BILL = 'vendor_bill'; |
|||
case CREDIT_NOTE = 'credit_note'; |
|||
|
|||
public function schema(): InvoiceSchema |
|||
{ |
|||
return match ($this) { |
|||
self::STUDENT_INVOICE => StudentInvoiceSchema::make(), |
|||
default => InvoiceSchema::make()->withCoaVisibility(), |
|||
}; |
|||
} |
|||
|
|||
public function dtoTransform(array $data): InvoiceDetailDTO |
|||
{ |
|||
return match ($this) { |
|||
self::STUDENT_INVOICE => StudentInvoiceDetailDTO::fromArray($data), |
|||
default => false |
|||
}; |
|||
} |
|||
|
|||
/** |
|||
* Resolve all field schemas, keyed by their input keys. |
|||
* |
|||
* @return array<string, InputSchemaField> |
|||
*/ |
|||
public function getSchema(): array |
|||
{ |
|||
return $this->schema()->getSchema(); |
|||
} |
|||
} |
|||
@ -1,16 +0,0 @@ |
|||
<?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'; |
|||
} |
|||
@ -1,18 +0,0 @@ |
|||
<?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'; |
|||
} |
|||
@ -1,38 +0,0 @@ |
|||
<?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 App\Domains\System\Traits\Model\HasPublicUlid; |
|||
use Database\Factories\Finance\ChartOfAccountFactory; |
|||
use Illuminate\Database\Eloquent\Attributes\Fillable; |
|||
use Illuminate\Database\Eloquent\Attributes\UsePolicy; |
|||
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 HasPublicUlid; |
|||
|
|||
protected $casts = [ |
|||
'classification' => AccountClassification::class, |
|||
'status' => LifecycleStatus::class, |
|||
]; |
|||
|
|||
protected static function newFactory(): Factory |
|||
{ |
|||
return ChartOfAccountFactory::new(); |
|||
} |
|||
} |
|||
@ -1,55 +0,0 @@ |
|||
<?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 App\Domains\System\Traits\Model\HasPublicUlid; |
|||
use Database\Factories\Finance\InvoiceFactory; |
|||
use Illuminate\Database\Eloquent\Attributes\Fillable; |
|||
use Illuminate\Database\Eloquent\Attributes\UsePolicy; |
|||
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 HasPublicUlid; |
|||
|
|||
protected $casts = [ |
|||
'amount' => MoneyCurrency::class, |
|||
'type' => InvoiceType::class, |
|||
'status' => InvoiceStatus::class, |
|||
]; |
|||
|
|||
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); |
|||
} |
|||
} |
|||
@ -1,42 +0,0 @@ |
|||
<?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, |
|||
]; |
|||
} |
|||
@ -1,49 +0,0 @@ |
|||
<?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 App\Domains\System\Traits\Model\HasPublicUlid; |
|||
use Database\Factories\Finance\PaymentFactory; |
|||
use Illuminate\Database\Eloquent\Attributes\Fillable; |
|||
use Illuminate\Database\Eloquent\Attributes\UsePolicy; |
|||
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 HasPublicUlid; |
|||
|
|||
protected $casts = [ |
|||
'amount' => MoneyCurrency::class, |
|||
'valid_until' => 'datetime_immutable', |
|||
'direction' => PaymentDirection::class, |
|||
'status' => PaymentStatus::class, |
|||
]; |
|||
|
|||
protected static function newFactory(): Factory |
|||
{ |
|||
return PaymentFactory::new(); |
|||
} |
|||
|
|||
public function transaction(): BelongsTo |
|||
{ |
|||
return $this->belongsTo(Invoice::class); |
|||
} |
|||
} |
|||
@ -1,24 +0,0 @@ |
|||
<?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); |
|||
} |
|||
} |
|||
@ -1,47 +0,0 @@ |
|||
<?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, |
|||
]; |
|||
} |
|||
@ -1,49 +0,0 @@ |
|||
<?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'); |
|||
} |
|||
} |
|||
@ -1,49 +0,0 @@ |
|||
<?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'); |
|||
} |
|||
} |
|||
@ -1,49 +0,0 @@ |
|||
<?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; |
|||
} |
|||
} |
|||
@ -1,49 +0,0 @@ |
|||
<?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'); |
|||
} |
|||
} |
|||
@ -1,49 +0,0 @@ |
|||
<?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'); |
|||
} |
|||
} |
|||
@ -1,49 +0,0 @@ |
|||
<?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; |
|||
} |
|||
} |
|||
@ -1,23 +0,0 @@ |
|||
<?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(); |
|||
} |
|||
} |
|||
@ -1,31 +0,0 @@ |
|||
<?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. |
|||
} |
|||
} |
|||
@ -1,79 +0,0 @@ |
|||
<?php |
|||
|
|||
namespace App\Domains\Finance\Schemas\Invoice; |
|||
|
|||
use App\Domains\Academic\Queries\Selection\SelectFacultyQuery; |
|||
use App\Domains\Academic\Queries\Selection\SelectStudyProgramQuery; |
|||
use App\Domains\Academic\Queries\Selection\SelectTermQuery; |
|||
use App\Domains\Finance\Support\Schemas\InvoiceSchema; |
|||
use App\UI\Enums\InputType; |
|||
use App\UI\Support\Schemas\InputSchema; |
|||
|
|||
class StudentInvoiceSchema |
|||
{ |
|||
public static function make(): InvoiceSchema |
|||
{ |
|||
return InvoiceSchema::make() |
|||
->addInput( |
|||
InputSchema::make() |
|||
->key('student_id') |
|||
->label(__('domains/finance/field.invoice.detail.student_id')) |
|||
->type(InputType::TEXTLINE) |
|||
->rules(['required']) |
|||
) |
|||
->addInput( |
|||
InputSchema::make() |
|||
->key('student_name') |
|||
->label(__('domains/finance/field.invoice.detail.student_name')) |
|||
->type(InputType::TEXTLINE) |
|||
->rules(['required', 'string']) |
|||
) |
|||
->addInput( |
|||
InputSchema::make() |
|||
->key('faculty') |
|||
->label(__('domains/finance/field.invoice.detail.faculty')) |
|||
->type(InputType::SELECT) |
|||
->rules(['required', 'string']) |
|||
->select2() |
|||
->live() |
|||
->options(fn () => SelectFacultyQuery::fetch()) |
|||
) |
|||
->addInput( |
|||
InputSchema::make() |
|||
->key('study_program') |
|||
->label(__('domains/finance/field.invoice.detail.study_program')) |
|||
->type(InputType::SELECT) |
|||
->rules(['required', 'string']) |
|||
->select2() |
|||
->dependsOn('faculty') |
|||
->setContextKeys(['faculty']) |
|||
->options(fn ($context) => SelectStudyProgramQuery::fetch($context)) |
|||
) |
|||
->addInput( |
|||
InputSchema::make() |
|||
->key('term_entry') |
|||
->label(__('domains/finance/field.invoice.detail.term_entry')) |
|||
->type(InputType::SELECT) |
|||
->rules(['required']) |
|||
->options(fn () => SelectTermQuery::fetch()) |
|||
->select2() |
|||
) |
|||
->addInput( |
|||
InputSchema::make() |
|||
->key('semester') |
|||
->label(__('domains/finance/field.invoice.detail.semester')) |
|||
->type(InputType::SELECT) |
|||
->rules(['required']) |
|||
->options(array_combine(range(1, 13), range(1, 13))) |
|||
->select2() |
|||
) |
|||
->addInput( |
|||
InputSchema::make() |
|||
->key('fee_type') |
|||
->label(__('domains/finance/field.invoice.detail.fee_type')) |
|||
->type(InputType::SELECT) |
|||
->rules(['required']) |
|||
->select2() |
|||
); |
|||
} |
|||
} |
|||
@ -1,25 +0,0 @@ |
|||
<?php |
|||
|
|||
namespace App\Domains\Finance\Support\Schemas; |
|||
|
|||
use App\UI\Support\Schemas\AbstractGroupSchema; |
|||
|
|||
class InvoiceSchema extends AbstractGroupSchema |
|||
{ |
|||
protected bool $coaVisibility = false; |
|||
|
|||
/** |
|||
* Fluent setter for COA visibility. |
|||
*/ |
|||
public function withCoaVisibility(bool $visible = true): static |
|||
{ |
|||
$this->coaVisibility = $visible; |
|||
|
|||
return $this; |
|||
} |
|||
|
|||
public function isCoaVisible(): bool |
|||
{ |
|||
return $this->coaVisibility; |
|||
} |
|||
} |
|||
@ -1,8 +1,8 @@ |
|||
<?php |
|||
|
|||
namespace App\Domains\Finance\Casts; |
|||
namespace App\Domains\System\Casts; |
|||
|
|||
use App\Domains\Finance\Support\ValueObjects\Money; |
|||
use App\Domains\System\Support\ValueObjects\Money; |
|||
use Illuminate\Contracts\Database\Eloquent\CastsAttributes; |
|||
use Illuminate\Database\Eloquent\Model; |
|||
use InvalidArgumentException; |
|||
@ -1,6 +1,6 @@ |
|||
<?php |
|||
|
|||
namespace App\Domains\Finance\Support\ValueObjects; |
|||
namespace App\Domains\System\Support\ValueObjects; |
|||
|
|||
use InvalidArgumentException; |
|||
use NumberFormatter; |
|||
@ -0,0 +1,21 @@ |
|||
<?php |
|||
|
|||
namespace App\Http\Controllers\Api\V1\Lookup; |
|||
|
|||
use App\Domains\Academic\Queries\Lookup\TermLookup; |
|||
use App\Http\Controllers\Controller; |
|||
use App\Http\Resources\LookupResource; |
|||
use Illuminate\Http\Request; |
|||
|
|||
class TermLookupController extends Controller |
|||
{ |
|||
public function __invoke(Request $request, TermLookup $lookup) |
|||
{ |
|||
$terms = $lookup->fetch()->map(fn ($term) => (object) [ |
|||
'id' => $term, |
|||
'text' => $term, |
|||
]); |
|||
|
|||
return LookupResource::collection($terms); |
|||
} |
|||
} |
|||
@ -1,32 +0,0 @@ |
|||
<?php |
|||
|
|||
namespace App\Http\Controllers\Web\Finance; |
|||
|
|||
use App\Attributes\LayoutData; |
|||
use App\Attributes\Seo; |
|||
use App\Http\Controllers\Controller; |
|||
use App\Http\DataTables\Finance\ChartOfAccountDataTable; |
|||
use Illuminate\Http\Request; |
|||
|
|||
class ChartOfAccountController extends Controller |
|||
{ |
|||
/** |
|||
* Handle the incoming request. |
|||
*/ |
|||
#[Seo( |
|||
title: 'domains/finance/seo.coa.title', |
|||
description: 'domains/finance/seo.coa.description', |
|||
keywords: 'domains/finance/seo.coa.keywords' |
|||
)] |
|||
#[LayoutData( |
|||
header: 'domains/finance/seo.coa.title', |
|||
breadcrumbs: [ |
|||
'ui/menu.dashboard' => 'dashboard', |
|||
'domains/finance/seo.coa.title' => '', |
|||
], |
|||
)] |
|||
public function __invoke(ChartOfAccountDataTable $dataTable) |
|||
{ |
|||
return $dataTable->render('pages.finance.chart-of-account.index'); |
|||
} |
|||
} |
|||
@ -1,32 +0,0 @@ |
|||
<?php |
|||
|
|||
namespace App\Http\Controllers\Web\Finance; |
|||
|
|||
use App\Attributes\LayoutData; |
|||
use App\Attributes\Seo; |
|||
use App\Http\Controllers\Controller; |
|||
use App\Http\DataTables\Finance\InvoiceDataTable; |
|||
use Illuminate\Http\Request; |
|||
|
|||
class InvoiceController extends Controller |
|||
{ |
|||
/** |
|||
* Handle the incoming request. |
|||
*/ |
|||
#[Seo( |
|||
title: 'domains/finance/seo.invoice.title', |
|||
description: 'domains/finance/seo.invoice.description', |
|||
keywords: 'domains/finance/seo.invoice.keywords' |
|||
)] |
|||
#[LayoutData( |
|||
header: 'domains/finance/seo.invoice.title', |
|||
breadcrumbs: [ |
|||
'ui/menu.dashboard' => 'dashboard', |
|||
'domains/finance/seo.invoice.title' => '', |
|||
], |
|||
)] |
|||
public function __invoke(InvoiceDataTable $dataTable) |
|||
{ |
|||
return $dataTable->render('pages.finance.invoice.index'); |
|||
} |
|||
} |
|||
@ -1,32 +0,0 @@ |
|||
<?php |
|||
|
|||
namespace App\Http\Controllers\Web\Finance; |
|||
|
|||
use App\Attributes\LayoutData; |
|||
use App\Attributes\Seo; |
|||
use App\Http\Controllers\Controller; |
|||
use App\Http\DataTables\Finance\ProductMappingDataTable; |
|||
use Illuminate\Http\Request; |
|||
|
|||
class ProductMappingController extends Controller |
|||
{ |
|||
/** |
|||
* Handle the incoming request. |
|||
*/ |
|||
#[Seo( |
|||
title: 'domains/finance/seo.product_mapping.title', |
|||
description: 'domains/finance/seo.product_mapping.description', |
|||
keywords: 'domains/finance/seo.product_mapping.keywords' |
|||
)] |
|||
#[LayoutData( |
|||
header: 'domains/finance/seo.product_mapping.title', |
|||
breadcrumbs: [ |
|||
'ui/menu.dashboard' => 'dashboard', |
|||
'domains/finance/seo.product_mapping.title' => '', |
|||
], |
|||
)] |
|||
public function __invoke(ProductMappingDataTable $dataTable) |
|||
{ |
|||
return $dataTable->render('pages.finance.product-mapping.index'); |
|||
} |
|||
} |
|||
@ -1,143 +0,0 @@ |
|||
<?php |
|||
|
|||
namespace App\Http\DataTables\Finance; |
|||
|
|||
use App\Domains\Finance\Models\ChartOfAccount; |
|||
use Illuminate\Database\Eloquent\Builder as QueryBuilder; |
|||
use Yajra\DataTables\EloquentDataTable; |
|||
use Yajra\DataTables\Html\Builder as HtmlBuilder; |
|||
use Yajra\DataTables\Html\Button; |
|||
use Yajra\DataTables\Html\Column; |
|||
use Yajra\DataTables\Services\DataTable; |
|||
|
|||
class ChartOfAccountDataTable extends DataTable |
|||
{ |
|||
/** |
|||
* Build the DataTable class. |
|||
* |
|||
* @param QueryBuilder<ChartOfAccount> $query Results from query() method. |
|||
*/ |
|||
public function dataTable(QueryBuilder $query): EloquentDataTable |
|||
{ |
|||
return (new EloquentDataTable($query)) |
|||
->editColumn('status', fn (ChartOfAccount $coa) => view('components.badge', [ |
|||
'label' => $coa->status->label(), |
|||
'variant' => $coa->status->variant(), |
|||
])) |
|||
->editColumn('classification', fn (ChartOfAccount $coa) => $coa->classification->label()) |
|||
->addColumn( |
|||
'action', |
|||
fn ($coa) => view('components.datatables.action-button', [ |
|||
'log' => true, |
|||
'edit' => [ |
|||
'modal' => 'chartofaccount-form-modal', |
|||
'permission' => auth()->user()->can('update', $coa), |
|||
], |
|||
'delete' => [ |
|||
'url' => null, |
|||
'title' => __('ui/button.delete'), |
|||
'message' => __('ui/confirmation.delete', ['resource' => __('resources.chart_of_account')]), |
|||
'success_message' => __('ui/crud.success.deleted', ['resource' => __('resources.chart_of_account')]), |
|||
'permission' => auth()->user()->can('delete', $coa), |
|||
], |
|||
'table_name' => 'chartofaccount-table', |
|||
'id' => $coa->ulid, |
|||
]) |
|||
) |
|||
->rawColumns(['action']) |
|||
->addIndexColumn(); |
|||
} |
|||
|
|||
/** |
|||
* Get the query source of dataTable. |
|||
* |
|||
* @return QueryBuilder<ChartOfAccount> |
|||
*/ |
|||
public function query(ChartOfAccount $model): QueryBuilder |
|||
{ |
|||
return $model->newQuery(); |
|||
} |
|||
|
|||
/** |
|||
* Optional method if you want to use the html builder. |
|||
*/ |
|||
public function html(): HtmlBuilder |
|||
{ |
|||
return $this->builder() |
|||
->setTableId('chartofaccount-table') |
|||
->columns($this->getColumns()) |
|||
->minifiedAjax() |
|||
->orderBy(-1) |
|||
->layout([ |
|||
'topStart' => [ |
|||
'rowClass' => 'row gap-1', |
|||
'className' => 'col-md-auto me-auto d-flex flex-sm-row flex-column justify-content-center justify-content-md-start align-items-center align-items-md-start gap-1', |
|||
'features' => ['buttons', 'pageLength'], |
|||
], |
|||
'topEnd' => [ |
|||
'className' => 'col-md-auto ms-auto d-flex flex-sm-row flex-column justify-content-center justify-content-md-end align-items-center align-items-md-start gap-1', |
|||
'features' => ['search'], |
|||
], |
|||
|
|||
'bottomStart' => 'info', |
|||
'bottomEnd' => 'paging', |
|||
]) |
|||
->parameters([ |
|||
'language' => [ |
|||
'search' => '', |
|||
'searchPlaceholder' => __('ui/button.lookup'), |
|||
], |
|||
'fixedColumns' => [ |
|||
'start' => 2, |
|||
], |
|||
'scrollX' => true, |
|||
'scrollCollapse' => true, |
|||
'responsive' => true, |
|||
]) |
|||
->buttons([ |
|||
Button::make('add') |
|||
->action('javascript:void(0)') |
|||
->attr(['data-coreui-toggle' => 'modal', 'data-coreui-target' => '#chartofaccount-form-modal']) |
|||
->text(svg('tabler-plus', ['width' => 16, 'height' => 16])->toHtml()) |
|||
->addClass('btn-sm'), |
|||
Button::make('reload') |
|||
->text(svg('tabler-reload', ['width' => 16, 'height' => 16])->toHtml()) |
|||
->addClass('btn-sm'), |
|||
]); |
|||
} |
|||
|
|||
/** |
|||
* Get the dataTable columns definition. |
|||
*/ |
|||
public function getColumns(): array |
|||
{ |
|||
return [ |
|||
Column::computed('DT_RowIndex') |
|||
->width(10) |
|||
->title('#'), |
|||
Column::make('code') |
|||
->title(__('domains/finance/field.coa.code')), |
|||
Column::make('name') |
|||
->title(__('domains/finance/field.coa.name')), |
|||
Column::make('classification') |
|||
->title(__('domains/finance/field.coa.classification')), |
|||
Column::make('status') |
|||
->width(100) |
|||
->title(__('domains/finance/field.coa.status')), |
|||
Column::computed('action') |
|||
->title(__('ui/label.actions')) |
|||
->exportable(false) |
|||
->printable(false) |
|||
->width(60) |
|||
->addClass('text-center'), |
|||
]; |
|||
} |
|||
|
|||
/** |
|||
* Get the filename for export. |
|||
*/ |
|||
protected function filename(): string |
|||
{ |
|||
return 'ChartOfAccount_'.date('YmdHis'); |
|||
} |
|||
} |
|||
@ -1,115 +0,0 @@ |
|||
<?php |
|||
|
|||
namespace App\Http\DataTables\Finance; |
|||
|
|||
use App\Domains\Finance\Models\Invoice; |
|||
use Illuminate\Database\Eloquent\Builder as QueryBuilder; |
|||
use Yajra\DataTables\EloquentDataTable; |
|||
use Yajra\DataTables\Html\Builder as HtmlBuilder; |
|||
use Yajra\DataTables\Html\Button; |
|||
use Yajra\DataTables\Html\Column; |
|||
use Yajra\DataTables\Services\DataTable; |
|||
|
|||
class InvoiceDataTable extends DataTable |
|||
{ |
|||
/** |
|||
* Build the DataTable class. |
|||
* |
|||
* @param QueryBuilder<Invoice> $query Results from query() method. |
|||
*/ |
|||
public function dataTable(QueryBuilder $query): EloquentDataTable |
|||
{ |
|||
return (new EloquentDataTable($query)) |
|||
->addColumn('action', 'invoice.action') |
|||
->setRowId('id'); |
|||
} |
|||
|
|||
/** |
|||
* Get the query source of dataTable. |
|||
* |
|||
* @return QueryBuilder<Invoice> |
|||
*/ |
|||
public function query(Invoice $model): QueryBuilder |
|||
{ |
|||
return $model->newQuery(); |
|||
} |
|||
|
|||
/** |
|||
* Optional method if you want to use the html builder. |
|||
*/ |
|||
public function html(): HtmlBuilder |
|||
{ |
|||
return $this->builder() |
|||
->setTableId('invoice-table') |
|||
->columns($this->getColumns()) |
|||
->minifiedAjax() |
|||
->orderBy(-1) |
|||
->layout([ |
|||
'topStart' => [ |
|||
'rowClass' => 'row gap-1', |
|||
'className' => 'col-md-auto me-auto d-flex flex-sm-row flex-column justify-content-center justify-content-md-start align-items-center align-items-md-start gap-1', |
|||
'features' => ['buttons', 'pageLength'], |
|||
], |
|||
'topEnd' => [ |
|||
'className' => 'col-md-auto ms-auto d-flex flex-sm-row flex-column justify-content-center justify-content-md-end align-items-center align-items-md-start gap-1', |
|||
'features' => ['search'], |
|||
], |
|||
|
|||
'bottomStart' => 'info', |
|||
'bottomEnd' => 'paging', |
|||
]) |
|||
->parameters([ |
|||
'language' => [ |
|||
'search' => '', |
|||
'searchPlaceholder' => __('ui/button.lookup'), |
|||
], |
|||
'fixedColumns' => [ |
|||
'start' => 2, |
|||
], |
|||
'scrollX' => true, |
|||
'scrollCollapse' => true, |
|||
'responsive' => true, |
|||
]) |
|||
->buttons([ |
|||
Button::make('add') |
|||
->action('javascript:void(0)') |
|||
->attr(['data-coreui-toggle' => 'modal', 'data-coreui-target' => '#invoice-form-modal']) |
|||
->text(svg('tabler-plus', ['width' => 16, 'height' => 16])->toHtml()) |
|||
->addClass('btn-sm'), |
|||
Button::make('reload') |
|||
->text(svg('tabler-reload', ['width' => 16, 'height' => 16])->toHtml()) |
|||
->addClass('btn-sm'), |
|||
]); |
|||
} |
|||
|
|||
/** |
|||
* Get the dataTable columns definition. |
|||
*/ |
|||
public function getColumns(): array |
|||
{ |
|||
return [ |
|||
Column::computed('DT_RowIndex') |
|||
->width(10) |
|||
->title('#'), |
|||
Column::make('name') |
|||
->title(__('domains/finance/field.invoice.name')), |
|||
Column::make('type') |
|||
->title(__('domains/finance/field.invoice.type')), |
|||
Column::make('amount') |
|||
->title(__('domains/finance/field.invoice.amount')), |
|||
Column::make('client.name') |
|||
->title(__('domains/finance/field.invoice.client_name')), |
|||
Column::make('status') |
|||
->width(100) |
|||
->title(__('domains/finance/field.invoice.status')), |
|||
]; |
|||
} |
|||
|
|||
/** |
|||
* Get the filename for export. |
|||
*/ |
|||
protected function filename(): string |
|||
{ |
|||
return 'Invoice_'.date('YmdHis'); |
|||
} |
|||
} |
|||
@ -1,137 +0,0 @@ |
|||
<?php |
|||
|
|||
namespace App\Http\DataTables\Finance; |
|||
|
|||
use App\Domains\Finance\Models\ProductMapping; |
|||
use Illuminate\Database\Eloquent\Builder as QueryBuilder; |
|||
use Yajra\DataTables\EloquentDataTable; |
|||
use Yajra\DataTables\Html\Builder as HtmlBuilder; |
|||
use Yajra\DataTables\Html\Button; |
|||
use Yajra\DataTables\Html\Column; |
|||
use Yajra\DataTables\Services\DataTable; |
|||
|
|||
class ProductMappingDataTable extends DataTable |
|||
{ |
|||
/** |
|||
* Build the DataTable class. |
|||
* |
|||
* @param QueryBuilder<ProductMapping> $query Results from query() method. |
|||
*/ |
|||
public function dataTable(QueryBuilder $query): EloquentDataTable |
|||
{ |
|||
return (new EloquentDataTable($query)) |
|||
->addColumn( |
|||
'action', |
|||
fn ($productMapping) => view('components.datatables.action-button', [ |
|||
'log' => true, |
|||
'edit' => [ |
|||
'modal' => 'product-mapping-form-modal', |
|||
'permission' => auth()->user()->can('update', $productMapping), |
|||
], |
|||
'delete' => [ |
|||
'url' => null, |
|||
'title' => __('ui/button.delete'), |
|||
'message' => __('ui/confirmation.delete', ['resource' => __('resources.product_mapping')]), |
|||
'success_message' => __('ui/crud.success.deleted', ['resource' => __('resources.product_mapping')]), |
|||
'permission' => auth()->user()->can('delete', $productMapping), |
|||
], |
|||
'table_name' => 'productmapping-table', |
|||
'id' => $productMapping->ulid, |
|||
]) |
|||
) |
|||
->rawColumns(['action']) |
|||
->addIndexColumn(); |
|||
} |
|||
|
|||
/** |
|||
* Get the query source of dataTable. |
|||
* |
|||
* @return QueryBuilder<ProductMapping> |
|||
*/ |
|||
public function query(ProductMapping $model): QueryBuilder |
|||
{ |
|||
return $model->newQuery(); |
|||
} |
|||
|
|||
/** |
|||
* Optional method if you want to use the html builder. |
|||
*/ |
|||
public function html(): HtmlBuilder |
|||
{ |
|||
return $this->builder() |
|||
->setTableId('productmapping-table') |
|||
->columns($this->getColumns()) |
|||
->minifiedAjax() |
|||
->orderBy(-1) |
|||
->layout([ |
|||
'topStart' => [ |
|||
'rowClass' => 'row gap-1', |
|||
'className' => 'col-md-auto me-auto d-flex flex-sm-row flex-column justify-content-center justify-content-md-start align-items-center align-items-md-start gap-1', |
|||
'features' => ['buttons', 'pageLength'], |
|||
], |
|||
'topEnd' => [ |
|||
'className' => 'col-md-auto ms-auto d-flex flex-sm-row flex-column justify-content-center justify-content-md-end align-items-center align-items-md-start gap-1', |
|||
'features' => ['search'], |
|||
], |
|||
|
|||
'bottomStart' => 'info', |
|||
'bottomEnd' => 'paging', |
|||
]) |
|||
->parameters([ |
|||
'language' => [ |
|||
'search' => '', |
|||
'searchPlaceholder' => __('ui/button.lookup'), |
|||
], |
|||
'fixedColumns' => [ |
|||
'start' => 2, |
|||
], |
|||
'scrollX' => true, |
|||
'scrollCollapse' => true, |
|||
'responsive' => true, |
|||
]) |
|||
->buttons([ |
|||
Button::make('add') |
|||
->action('javascript:void(0)') |
|||
->attr(['data-coreui-toggle' => 'modal', 'data-coreui-target' => '#product-mapping-form-modal']) |
|||
->text(svg('tabler-plus', ['width' => 16, 'height' => 16])->toHtml()) |
|||
->addClass('btn-sm'), |
|||
Button::make('reload') |
|||
->text(svg('tabler-reload', ['width' => 16, 'height' => 16])->toHtml()) |
|||
->addClass('btn-sm'), |
|||
]); |
|||
} |
|||
|
|||
/** |
|||
* Get the dataTable columns definition. |
|||
*/ |
|||
public function getColumns(): array |
|||
{ |
|||
return [ |
|||
Column::computed('DT_RowIndex') |
|||
->width(10) |
|||
->title('#'), |
|||
Column::make('code') |
|||
->title(__('domains/finance/field.product_mapping.code')), |
|||
Column::make('name') |
|||
->title(__('domains/finance/field.product_mapping.name')), |
|||
Column::make('chart_of_account.name') |
|||
->title(__('domains/finance/field.product_mapping.coa_name')), |
|||
Column::make('client.name') |
|||
->title(__('domains/finance/field.product_mapping.client_name')), |
|||
Column::computed('action') |
|||
->title(__('ui/label.actions')) |
|||
->exportable(false) |
|||
->printable(false) |
|||
->width(60) |
|||
->addClass('text-center'), |
|||
]; |
|||
} |
|||
|
|||
/** |
|||
* Get the filename for export. |
|||
*/ |
|||
protected function filename(): string |
|||
{ |
|||
return 'ProductMapping_'.date('YmdHis'); |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
<?php |
|||
|
|||
|
|||
return [ |
|||
'fee_type' => [ |
|||
'not_defined' => 'Not Set', |
|||
'partially_defined' => 'Partial', |
|||
'completely_defined' => 'Complete', |
|||
], |
|||
]; |
|||
@ -1,38 +0,0 @@ |
|||
<?php |
|||
|
|||
use App\Domains\Finance\Enums\AccountClassification; |
|||
use App\Domains\Finance\Enums\InvoiceStatus; |
|||
use App\Domains\Finance\Enums\InvoiceType; |
|||
use App\Domains\Finance\Enums\PaymentDirection; |
|||
use App\Domains\Finance\Enums\PaymentStatus; |
|||
|
|||
return [ |
|||
'invoice_status' => [ |
|||
InvoiceStatus::PAID->value => 'Paid', |
|||
InvoiceStatus::PENDING->value => 'Pending', |
|||
InvoiceStatus::PARTIALLY_PAID->value => 'Partially Paid', |
|||
InvoiceStatus::OVERDUE->value => 'Overdue', |
|||
], |
|||
'invoice_type' => [ |
|||
InvoiceType::STUDENT_INVOICE->value => 'Student Invoice', |
|||
InvoiceType::VENDOR_BILL->value => 'Vendor Bill', |
|||
InvoiceType::CREDIT_NOTE->value => 'Credit Note', |
|||
], |
|||
'payment_status' => [ |
|||
PaymentStatus::PENDING->value => 'Pending', |
|||
PaymentStatus::SUCCESS->value => 'Success', |
|||
PaymentStatus::FAILED->value => 'Failed', |
|||
PaymentStatus::EXPIRED->value => 'Expired', |
|||
], |
|||
'payment_direction' => [ |
|||
PaymentDirection::RECEIPT->value => 'Receipt', |
|||
PaymentDirection::DISBURSEMENT->value => 'Disbursement', |
|||
], |
|||
'account_classification' => [ |
|||
AccountClassification::ASSET->value => 'Asset', |
|||
AccountClassification::LIABILITY->value => 'Liability', |
|||
AccountClassification::EQUITY->value => 'Equity', |
|||
AccountClassification::REVENUE->value => 'Revenue', |
|||
AccountClassification::EXPENSE->value => 'Expense', |
|||
], |
|||
]; |
|||
@ -1,50 +0,0 @@ |
|||
<?php |
|||
|
|||
return [ |
|||
'coa' => [ |
|||
'code' => 'Account Code', |
|||
'name' => 'Account Name', |
|||
'classification' => 'Classification', |
|||
'status' => 'Status', |
|||
'parent' => 'Derived From', |
|||
], |
|||
'invoice' => [ |
|||
'name' => 'Invoice Name', |
|||
'code' => 'Invoice Code', |
|||
'type' => 'Invoice Type', |
|||
'amount' => 'Invoice Amount', |
|||
'client_name' => 'Client Name', |
|||
'status' => 'Status', |
|||
'coa_name' => 'Account Name (COA)', |
|||
'detail' => [ |
|||
// Detail for Student |
|||
'student_name' => 'Student Name', |
|||
'student_id' => 'Student ID', |
|||
'faculty' => 'Faculty', |
|||
'study_program' => 'Study Program', |
|||
'term_entry' => 'Term Entry', |
|||
'fee_type' => 'Fee Type', |
|||
'semester' => 'Semester', |
|||
|
|||
// Vendor Bill |
|||
'vendor_name' => 'Vendor Name', |
|||
'vendor_id' => 'Vendor ID', |
|||
], |
|||
], |
|||
'payment' => [ |
|||
'virtual_account' => 'Virtual Account', |
|||
'bank_ref_id' => 'Bank Reference Code', |
|||
'bank_name' => 'Bank Name', |
|||
'nominal' => 'Nominal', |
|||
'validity' => 'Validity', |
|||
'payment_date' => 'Payment Date', |
|||
'direction' => 'Direction', |
|||
'status' => 'Status', |
|||
], |
|||
'product_mapping' => [ |
|||
'code' => 'Product Code', |
|||
'name' => 'Product Name', |
|||
'coa_name' => 'Account Name (COA)', |
|||
'client_name' => 'Client Name', |
|||
], |
|||
]; |
|||
@ -1,19 +0,0 @@ |
|||
<?php |
|||
|
|||
return [ |
|||
'coa' => [ |
|||
'title' => 'Chart of Accounts (COA) Data', |
|||
'description' => 'Manage chart of accounts for financial records.', |
|||
'keywords' => 'chart of accounts, coa, accounting, finance', |
|||
], |
|||
'invoice' => [ |
|||
'title' => 'Invoice Data', |
|||
'description' => 'Manage student payment invoices.', |
|||
'keywords' => 'invoice, payment, finance', |
|||
], |
|||
'product_mapping' => [ |
|||
'title' => 'Product Mapping Data', |
|||
'description' => 'Manage cost product mappings with Chart of Accounts (COA).', |
|||
'keywords' => 'product mapping, product, coa, finance', |
|||
], |
|||
]; |
|||
@ -0,0 +1,7 @@ |
|||
<?php |
|||
|
|||
return [ |
|||
'select' => 'Select :attribute', |
|||
'email' => 'name@example.com', |
|||
'filter' => ':attribute Filter', |
|||
]; |
|||
@ -0,0 +1,9 @@ |
|||
<?php |
|||
|
|||
return [ |
|||
'fee_type' => [ |
|||
'not_defined' => 'Not Set', |
|||
'partially_defined' => 'Partial', |
|||
'completely_defined' => 'Complete', |
|||
], |
|||
]; |
|||
@ -0,0 +1,7 @@ |
|||
<?php |
|||
|
|||
return [ |
|||
'select' => 'Pilih :attribute', |
|||
'email' => 'nama@contoh.com', |
|||
'filter' => 'Filter :attribute', |
|||
]; |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue