first
This commit is contained in:
39
app/Services/Finance/BankVerificationService.php
Normal file
39
app/Services/Finance/BankVerificationService.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Finance;
|
||||
|
||||
use App\Models\BankVerification;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class BankVerificationService
|
||||
{
|
||||
/**
|
||||
* @param array{status: string, finance_note?: string|null} $data
|
||||
*/
|
||||
public function update(BankVerification $verification, User $actor, array $data): BankVerification
|
||||
{
|
||||
return DB::transaction(function () use ($verification, $actor, $data): BankVerification {
|
||||
$before = $verification->only(['status', 'finance_note', 'verified_by_user_id', 'verified_at']);
|
||||
|
||||
$verification->forceFill([
|
||||
'status' => $data['status'],
|
||||
'finance_note' => $data['finance_note'] ?? null,
|
||||
'verified_by_user_id' => $actor->id,
|
||||
'verified_at' => now(),
|
||||
])->save();
|
||||
|
||||
activity('finance')
|
||||
->performedOn($verification)
|
||||
->causedBy($actor)
|
||||
->withProperties([
|
||||
'before' => $before,
|
||||
'after' => $verification->only(['status', 'finance_note', 'verified_by_user_id', 'verified_at']),
|
||||
'application_id' => $verification->application_id,
|
||||
])
|
||||
->log('bank_verification_updated');
|
||||
|
||||
return $verification;
|
||||
});
|
||||
}
|
||||
}
|
||||
58
app/Services/Finance/FinanceExportService.php
Normal file
58
app/Services/Finance/FinanceExportService.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Finance;
|
||||
|
||||
use App\Exports\FinanceVerificationExport;
|
||||
use App\Models\Application;
|
||||
use App\Models\ExportLog;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class FinanceExportService
|
||||
{
|
||||
public function __construct(
|
||||
private readonly FinanceVerificationQuery $verificationQuery,
|
||||
private readonly FinanceVerificationExport $export,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $filters
|
||||
*/
|
||||
public function export(User $actor, array $filters): ExportLog
|
||||
{
|
||||
$verifications = $this->verificationQuery->build($filters)->get();
|
||||
$fileName = 'finance-verification-'.now()->format('Ymd-His').'.xlsx';
|
||||
$path = 'exports/finance/'.$fileName;
|
||||
|
||||
Storage::disk('local')->makeDirectory('exports/finance');
|
||||
$absolutePath = Storage::disk('local')->path($path);
|
||||
|
||||
$this->export->write($verifications, $absolutePath);
|
||||
|
||||
$firstApplication = $verifications->first()?->application;
|
||||
$electionId = $firstApplication instanceof Application ? $firstApplication->election_id : null;
|
||||
|
||||
$log = ExportLog::query()->create([
|
||||
'election_id' => $electionId,
|
||||
'generated_by_user_id' => $actor->id,
|
||||
'generated_at' => now(),
|
||||
'report_type' => 'finance_verification_list',
|
||||
'filter_parameters' => $filters,
|
||||
'file_name' => $fileName,
|
||||
'disk' => 'local',
|
||||
'path' => $path,
|
||||
]);
|
||||
|
||||
activity('exports')
|
||||
->performedOn($log)
|
||||
->causedBy($actor)
|
||||
->withProperties([
|
||||
'report_type' => 'finance_verification_list',
|
||||
'filters' => $filters,
|
||||
'row_count' => $verifications->count(),
|
||||
])
|
||||
->log('finance_verification_export_generated');
|
||||
|
||||
return $log;
|
||||
}
|
||||
}
|
||||
58
app/Services/Finance/FinanceVerificationQuery.php
Normal file
58
app/Services/Finance/FinanceVerificationQuery.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Finance;
|
||||
|
||||
use App\Models\BankVerification;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class FinanceVerificationQuery
|
||||
{
|
||||
/**
|
||||
* @param array<string, mixed> $filters
|
||||
* @return Builder<BankVerification>
|
||||
*/
|
||||
public function build(array $filters = []): Builder
|
||||
{
|
||||
return BankVerification::query()
|
||||
->with([
|
||||
'application.election',
|
||||
'application.pusatMengundi',
|
||||
'application.approvedPosition',
|
||||
'application.requestedPosition',
|
||||
'application.documents',
|
||||
'application.staffAssignments.position',
|
||||
'verifiedBy',
|
||||
])
|
||||
->whereHas('application', function (Builder $query) use ($filters): void {
|
||||
$query->whereIn('status', ['approved', 'assigned'])
|
||||
->when(! empty($filters['pusat_mengundi_id']), fn (Builder $nested) => $nested->where('pusat_mengundi_id', $filters['pusat_mengundi_id']))
|
||||
->when(! empty($filters['role_id']), function (Builder $nested) use ($filters): void {
|
||||
$nested->where(function (Builder $roleQuery) use ($filters): void {
|
||||
$roleQuery->where('approved_position_id', $filters['role_id'])
|
||||
->orWhere(function (Builder $fallback) use ($filters): void {
|
||||
$fallback->whereNull('approved_position_id')
|
||||
->where('requested_position_id', $filters['role_id']);
|
||||
});
|
||||
});
|
||||
})
|
||||
->when(! empty($filters['missing_account_number']), function (Builder $nested): void {
|
||||
$nested->where(function (Builder $accountQuery): void {
|
||||
$accountQuery->whereNull('bank_account_number')
|
||||
->orWhere('bank_account_number', '');
|
||||
});
|
||||
})
|
||||
->when(! empty($filters['missing_bank_statement']), function (Builder $nested): void {
|
||||
$nested->whereDoesntHave('documents', fn (Builder $documentQuery) => $documentQuery->where('document_type', 'bank_statement'));
|
||||
})
|
||||
->when(! empty($filters['q']), function (Builder $nested) use ($filters): void {
|
||||
$term = '%'.$filters['q'].'%';
|
||||
$nested->where(function (Builder $keywordQuery) use ($term): void {
|
||||
$keywordQuery->where('name', 'like', $term)
|
||||
->orWhere('ic_number', 'like', $term)
|
||||
->orWhere('email', 'like', $term);
|
||||
});
|
||||
});
|
||||
})
|
||||
->when(! empty($filters['status']), fn (Builder $query) => $query->where('status', $filters['status']));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user