Merge branch 'new'
# Conflicts: # app/Http/Controllers/PrintStatementController.php # app/Jobs/GenerateBiayaKartuCsvJob.php # app/Jobs/SendStatementEmailJob.php # app/Mail/StatementEmail.php # resources/views/statements/email.blade.php # resources/views/statements/index.blade.php
This commit is contained in:
@@ -12,6 +12,7 @@ use Modules\Webstatement\{
|
||||
Http\Requests\PrintStatementRequest,
|
||||
Mail\StatementEmail,
|
||||
Models\PrintStatementLog,
|
||||
Models\Account,
|
||||
Models\AccountBalance,
|
||||
Jobs\ExportStatementPeriodJob
|
||||
};
|
||||
@@ -24,9 +25,15 @@ use ZipArchive;
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$branches = Branch::orderBy('name')->get();
|
||||
$branches = Branch::whereNotNull('customer_company')
|
||||
->where('code', '!=', 'ID0019999')
|
||||
->orderBy('name')
|
||||
->get();
|
||||
|
||||
return view('webstatement::statements.index', compact('branches'));
|
||||
$branch = Branch::find(Auth::user()->branch_id);
|
||||
$multiBranch = session('MULTI_BRANCH') ?? false;
|
||||
|
||||
return view('webstatement::statements.index', compact('branches', 'branch', 'multiBranch'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -35,33 +42,67 @@ use ZipArchive;
|
||||
*/
|
||||
public function store(PrintStatementRequest $request)
|
||||
{
|
||||
// Add account verification before storing
|
||||
$accountNumber = $request->input('account_number'); // Assuming this is the field name for account number
|
||||
// First, check if the account exists and get branch information
|
||||
$account = Account::where('account_number', $accountNumber)->first();
|
||||
if ($account) {
|
||||
$branch_code = $account->branch_code;
|
||||
$userBranchId = session('branch_id'); // Assuming branch ID is stored in session
|
||||
$multiBranch = session('MULTI_BRANCH');
|
||||
|
||||
if (!$multiBranch) {
|
||||
// Check if account branch matches user's branch
|
||||
if ($account->branch_id !== $userBranchId) {
|
||||
return redirect()->route('statements.index')
|
||||
->with('error', 'Nomor rekening tidak sesuai dengan cabang Anda. Transaksi tidak dapat dilanjutkan.');
|
||||
}
|
||||
}
|
||||
|
||||
// Check if account belongs to restricted branch ID0019999
|
||||
if ($account->branch_id === 'ID0019999') {
|
||||
return redirect()->route('statements.index')
|
||||
->with('error', 'Nomor rekening terdaftar pada cabang khusus. Silakan hubungi bagian HC untuk informasi lebih lanjut.');
|
||||
}
|
||||
|
||||
// If all checks pass, proceed with storing data
|
||||
// Your existing store logic here
|
||||
|
||||
} else {
|
||||
// Account not found
|
||||
return redirect()->route('statements.index')
|
||||
->with('error', 'Nomor rekening tidak ditemukan dalam sistem.');
|
||||
}
|
||||
|
||||
DB::beginTransaction();
|
||||
|
||||
try {
|
||||
$validated = $request->validated();
|
||||
|
||||
// Add user tracking data dan field baru untuk single account request
|
||||
$validated['user_id'] = Auth::id();
|
||||
$validated['created_by'] = Auth::id();
|
||||
$validated['ip_address'] = $request->ip();
|
||||
$validated['user_agent'] = $request->userAgent();
|
||||
$validated['request_type'] = 'single_account'; // Default untuk request manual
|
||||
$validated['status'] = 'pending'; // Status awal
|
||||
$validated['total_accounts'] = 1; // Untuk single account
|
||||
$validated['user_id'] = Auth::id();
|
||||
$validated['created_by'] = Auth::id();
|
||||
$validated['ip_address'] = $request->ip();
|
||||
$validated['user_agent'] = $request->userAgent();
|
||||
$validated['request_type'] = 'single_account'; // Default untuk request manual
|
||||
$validated['status'] = 'pending'; // Status awal
|
||||
$validated['authorization_status'] = 'approved'; // Status otorisasi awal
|
||||
$validated['total_accounts'] = 1; // Untuk single account
|
||||
$validated['processed_accounts'] = 0;
|
||||
$validated['success_count'] = 0;
|
||||
$validated['failed_count'] = 0;
|
||||
$validated['stmt_sent_type'] = implode(',', $request->input('stmt_sent_type'));
|
||||
$validated['branch_code'] = $branch_code; // Awal tidak tersedia
|
||||
|
||||
// Create the statement log
|
||||
$statement = PrintStatementLog::create($validated);
|
||||
|
||||
// Log aktivitas
|
||||
Log::info('Statement request created', [
|
||||
'statement_id' => $statement->id,
|
||||
'user_id' => Auth::id(),
|
||||
'statement_id' => $statement->id,
|
||||
'user_id' => Auth::id(),
|
||||
'account_number' => $statement->account_number,
|
||||
'request_type' => $statement->request_type
|
||||
'request_type' => $statement->request_type
|
||||
]);
|
||||
|
||||
// Process statement availability check
|
||||
@@ -69,21 +110,26 @@ use ZipArchive;
|
||||
if(!$statement->is_available){
|
||||
$this->printStatementRekening($statement->account_number,$statement->period_from,$statement->period_to,$statement->stmt_sent_type);
|
||||
}
|
||||
|
||||
$statement = PrintStatementLog::find($statement->id);
|
||||
if($statement->email){
|
||||
$this->sendEmail($statement->id);
|
||||
}
|
||||
DB::commit();
|
||||
|
||||
return redirect()->route('statements.index')
|
||||
->with('success', 'Statement request has been created successfully.');
|
||||
->with('success', 'Statement request has been created successfully.');
|
||||
} catch (Exception $e) {
|
||||
DB::rollBack();
|
||||
|
||||
Log::error('Failed to create statement request', [
|
||||
'error' => $e->getMessage(),
|
||||
'error' => $e->getMessage(),
|
||||
'user_id' => Auth::id()
|
||||
]);
|
||||
|
||||
return redirect()->back()
|
||||
->withInput()
|
||||
->with('error', 'Failed to create statement request: ' . $e->getMessage());
|
||||
->withInput()
|
||||
->with('error', 'Failed to create statement request: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,19 +151,26 @@ use ZipArchive;
|
||||
DB::beginTransaction();
|
||||
|
||||
try {
|
||||
$disk = Storage::disk('sftpStatement');
|
||||
$filePath = "{$statement->period_from}/Print/{$statement->branch_code}/{$statement->account_number}.pdf";
|
||||
$disk = Storage::disk('sftpStatement');
|
||||
$filePath = "{$statement->period_from}/{$statement->branch_code}/{$statement->account_number}_{$statement->period_from}.pdf";
|
||||
|
||||
// Log untuk debugging
|
||||
Log::info('Checking SFTP file path', [
|
||||
'file_path' => $filePath,
|
||||
'sftp_root' => config('filesystems.disks.sftpStatement.root'),
|
||||
'full_path' => config('filesystems.disks.sftpStatement.root') . '/' . $filePath
|
||||
]);
|
||||
|
||||
if ($statement->is_period_range && $statement->period_to) {
|
||||
$periodFrom = Carbon::createFromFormat('Ym', $statement->period_from);
|
||||
$periodTo = Carbon::createFromFormat('Ym', $statement->period_to);
|
||||
$periodTo = Carbon::createFromFormat('Ym', $statement->period_to);
|
||||
|
||||
$missingPeriods = [];
|
||||
$missingPeriods = [];
|
||||
$availablePeriods = [];
|
||||
|
||||
for ($period = clone $periodFrom; $period->lte($periodTo); $period->addMonth()) {
|
||||
$periodFormatted = $period->format('Ym');
|
||||
$periodPath = $periodFormatted . "/Print/{$statement->branch_code}/{$statement->account_number}.pdf";
|
||||
$periodPath = $periodFormatted . "/{$statement->branch_code}/{$statement->account_number}_{$periodFormatted}.pdf";
|
||||
|
||||
if ($disk->exists($periodPath)) {
|
||||
$availablePeriods[] = $periodFormatted;
|
||||
@@ -130,55 +183,55 @@ use ZipArchive;
|
||||
$notes = "Missing periods: " . implode(', ', $missingPeriods);
|
||||
$statement->update([
|
||||
'is_available' => false,
|
||||
'remarks' => $notes,
|
||||
'updated_by' => Auth::id(),
|
||||
'status' => 'failed'
|
||||
'remarks' => $notes,
|
||||
'updated_by' => Auth::id(),
|
||||
'status' => 'failed'
|
||||
]);
|
||||
|
||||
Log::warning('Statement not available - missing periods', [
|
||||
'statement_id' => $statement->id,
|
||||
'statement_id' => $statement->id,
|
||||
'missing_periods' => $missingPeriods
|
||||
]);
|
||||
} else {
|
||||
$statement->update([
|
||||
'is_available' => true,
|
||||
'updated_by' => Auth::id(),
|
||||
'status' => 'completed',
|
||||
'is_available' => true,
|
||||
'updated_by' => Auth::id(),
|
||||
'status' => 'completed',
|
||||
'processed_accounts' => 1,
|
||||
'success_count' => 1
|
||||
'success_count' => 1
|
||||
]);
|
||||
|
||||
Log::info('Statement available - all periods found', [
|
||||
'statement_id' => $statement->id,
|
||||
'statement_id' => $statement->id,
|
||||
'available_periods' => $availablePeriods
|
||||
]);
|
||||
}
|
||||
} else if ($disk->exists($filePath)) {
|
||||
$statement->update([
|
||||
'is_available' => true,
|
||||
'updated_by' => Auth::id(),
|
||||
'status' => 'completed',
|
||||
'is_available' => true,
|
||||
'updated_by' => Auth::id(),
|
||||
'status' => 'completed',
|
||||
'processed_accounts' => 1,
|
||||
'success_count' => 1
|
||||
'success_count' => 1
|
||||
]);
|
||||
|
||||
Log::info('Statement available', [
|
||||
'statement_id' => $statement->id,
|
||||
'file_path' => $filePath
|
||||
'file_path' => $filePath
|
||||
]);
|
||||
} else {
|
||||
$statement->update([
|
||||
'is_available' => false,
|
||||
'updated_by' => Auth::id(),
|
||||
'status' => 'failed',
|
||||
'is_available' => false,
|
||||
'updated_by' => Auth::id(),
|
||||
'status' => 'failed',
|
||||
'processed_accounts' => 1,
|
||||
'failed_count' => 1,
|
||||
'error_message' => 'Statement file not found'
|
||||
'failed_count' => 1,
|
||||
'error_message' => 'Statement file not found'
|
||||
]);
|
||||
|
||||
Log::warning('Statement not available', [
|
||||
'statement_id' => $statement->id,
|
||||
'file_path' => $filePath
|
||||
'file_path' => $filePath
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -188,14 +241,14 @@ use ZipArchive;
|
||||
|
||||
Log::error('Error checking statement availability', [
|
||||
'statement_id' => $statement->id,
|
||||
'error' => $e->getMessage()
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
|
||||
$statement->update([
|
||||
'is_available' => false,
|
||||
'status' => 'failed',
|
||||
'is_available' => false,
|
||||
'status' => 'failed',
|
||||
'error_message' => $e->getMessage(),
|
||||
'updated_by' => Auth::id()
|
||||
'updated_by' => Auth::id()
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -226,33 +279,161 @@ use ZipArchive;
|
||||
$statement->update([
|
||||
'is_downloaded' => true,
|
||||
'downloaded_at' => now(),
|
||||
'updated_by' => Auth::id()
|
||||
'updated_by' => Auth::id()
|
||||
]);
|
||||
|
||||
Log::info('Statement downloaded', [
|
||||
'statement_id' => $statement->id,
|
||||
'user_id' => Auth::id(),
|
||||
'statement_id' => $statement->id,
|
||||
'user_id' => Auth::id(),
|
||||
'account_number' => $statement->account_number
|
||||
]);
|
||||
|
||||
DB::commit();
|
||||
|
||||
// Generate or fetch the statement file
|
||||
$disk = Storage::disk('sftpStatement');
|
||||
$filePath = "{$statement->period_from}/Print/{$statement->branch_code}/{$statement->account_number}.pdf";
|
||||
$disk = Storage::disk('sftpStatement');
|
||||
$filePath = "{$statement->period_from}/{$statement->branch_code}/{$statement->account_number}_{$statement->period_from}.pdf";
|
||||
|
||||
if ($statement->is_period_range && $statement->period_to) {
|
||||
// Handle period range download (existing logic)
|
||||
// ... existing zip creation logic ...
|
||||
// Log: Memulai proses download period range
|
||||
Log::info('Starting period range download', [
|
||||
'statement_id' => $statement->id,
|
||||
'period_from' => $statement->period_from,
|
||||
'period_to' => $statement->period_to
|
||||
]);
|
||||
|
||||
/**
|
||||
* Handle period range download dengan membuat zip file
|
||||
* yang berisi semua statement dalam rentang periode
|
||||
*/
|
||||
$periodFrom = Carbon::createFromFormat('Ym', $statement->period_from);
|
||||
$periodTo = Carbon::createFromFormat('Ym', $statement->period_to);
|
||||
|
||||
// Loop through each month in the range
|
||||
$missingPeriods = [];
|
||||
$availablePeriods = [];
|
||||
|
||||
for ($period = clone $periodFrom; $period->lte($periodTo); $period->addMonth()) {
|
||||
$periodFormatted = $period->format('Ym');
|
||||
$periodPath = $periodFormatted . "/{$statement->branch_code}/{$statement->account_number}_{$periodFormatted}.pdf";
|
||||
|
||||
if ($disk->exists($periodPath)) {
|
||||
$availablePeriods[] = $periodFormatted;
|
||||
Log::info('Period available for download', [
|
||||
'period' => $periodFormatted,
|
||||
'path' => $periodPath
|
||||
]);
|
||||
} else {
|
||||
$missingPeriods[] = $periodFormatted;
|
||||
Log::warning('Period not available for download', [
|
||||
'period' => $periodFormatted,
|
||||
'path' => $periodPath
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// If any period is available, create a zip and download it
|
||||
if (count($availablePeriods) > 0) {
|
||||
/**
|
||||
* Membuat zip file temporary untuk download
|
||||
* dengan semua statement yang tersedia dalam periode
|
||||
*/
|
||||
$zipFileName = "{$statement->account_number}_{$statement->period_from}_to_{$statement->period_to}.zip";
|
||||
$zipFilePath = storage_path("app/temp/{$zipFileName}");
|
||||
|
||||
// Ensure the temp directory exists
|
||||
if (!file_exists(storage_path('app/temp'))) {
|
||||
mkdir(storage_path('app/temp'), 0755, true);
|
||||
Log::info('Created temp directory for zip files');
|
||||
}
|
||||
|
||||
// Create a new zip archive
|
||||
$zip = new ZipArchive();
|
||||
if ($zip->open($zipFilePath, ZipArchive::CREATE | ZipArchive::OVERWRITE) === true) {
|
||||
Log::info('Zip archive created successfully', ['zip_path' => $zipFilePath]);
|
||||
|
||||
// Add each available statement to the zip
|
||||
foreach ($availablePeriods as $period) {
|
||||
$periodFilePath = "{$period}/{$statement->branch_code}/{$statement->account_number}_{$period}.pdf";
|
||||
$localFilePath = storage_path("app/temp/{$statement->account_number}_{$period}.pdf");
|
||||
|
||||
try {
|
||||
// Download the file from SFTP to local storage temporarily
|
||||
file_put_contents($localFilePath, $disk->get($periodFilePath));
|
||||
|
||||
// Add the file to the zip
|
||||
$zip->addFile($localFilePath, "{$statement->account_number}_{$period}.pdf");
|
||||
|
||||
Log::info('Added file to zip', [
|
||||
'period' => $period,
|
||||
'local_path' => $localFilePath
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
Log::error('Failed to add file to zip', [
|
||||
'period' => $period,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
$zip->close();
|
||||
Log::info('Zip archive closed successfully');
|
||||
|
||||
// Return the zip file for download
|
||||
$response = response()->download($zipFilePath, $zipFileName)->deleteFileAfterSend(true);
|
||||
|
||||
// Clean up temporary PDF files
|
||||
foreach ($availablePeriods as $period) {
|
||||
$localFilePath = storage_path("app/temp/{$statement->account_number}_{$period}.pdf");
|
||||
if (file_exists($localFilePath)) {
|
||||
unlink($localFilePath);
|
||||
Log::info('Cleaned up temporary file', ['file' => $localFilePath]);
|
||||
}
|
||||
}
|
||||
|
||||
Log::info('Period range download completed successfully', [
|
||||
'statement_id' => $statement->id,
|
||||
'available_periods' => count($availablePeriods),
|
||||
'missing_periods' => count($missingPeriods)
|
||||
]);
|
||||
|
||||
return $response;
|
||||
} else {
|
||||
Log::error('Failed to create zip archive', ['zip_path' => $zipFilePath]);
|
||||
return back()->with('error', 'Failed to create zip archive for download.');
|
||||
}
|
||||
} else {
|
||||
Log::warning('No statements available for download in period range', [
|
||||
'statement_id' => $statement->id,
|
||||
'missing_periods' => $missingPeriods
|
||||
]);
|
||||
return back()->with('error', 'No statements available for download in the specified period range.');
|
||||
}
|
||||
} else if ($disk->exists($filePath)) {
|
||||
/**
|
||||
* Handle single period download
|
||||
* Download file PDF tunggal untuk periode tertentu
|
||||
*/
|
||||
Log::info('Single period download', [
|
||||
'statement_id' => $statement->id,
|
||||
'file_path' => $filePath
|
||||
]);
|
||||
|
||||
return $disk->download($filePath, "{$statement->account_number}_{$statement->period_from}.pdf");
|
||||
} else {
|
||||
Log::warning('Statement file not found', [
|
||||
'statement_id' => $statement->id,
|
||||
'file_path' => $filePath
|
||||
]);
|
||||
return back()->with('error', 'Statement file not found.');
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
DB::rollBack();
|
||||
|
||||
Log::error('Failed to download statement', [
|
||||
'statement_id' => $statement->id,
|
||||
'error' => $e->getMessage()
|
||||
'error' => $e->getMessage(),
|
||||
'trace' => $e->getTraceAsString()
|
||||
]);
|
||||
|
||||
return back()->with('error', 'Failed to download statement: ' . $e->getMessage());
|
||||
@@ -298,6 +479,13 @@ use ZipArchive;
|
||||
// Retrieve data from the database
|
||||
$query = PrintStatementLog::query();
|
||||
|
||||
if (!auth()->user()->hasRole('administrator')) {
|
||||
$query->where(function($q) {
|
||||
$q->where('user_id', Auth::id())
|
||||
->orWhere('branch_code', Auth::user()->branch->code);
|
||||
});
|
||||
}
|
||||
|
||||
// Apply search filter if provided
|
||||
if ($request->has('search') && !empty($request->get('search'))) {
|
||||
$search = $request->get('search');
|
||||
@@ -340,13 +528,13 @@ use ZipArchive;
|
||||
|
||||
// Map frontend column names to database column names if needed
|
||||
$columnMap = [
|
||||
'branch' => 'branch_code',
|
||||
'account' => 'account_number',
|
||||
'period' => 'period_from',
|
||||
'auth_status' => 'authorization_status',
|
||||
'branch' => 'branch_code',
|
||||
'account' => 'account_number',
|
||||
'period' => 'period_from',
|
||||
'auth_status' => 'authorization_status',
|
||||
'request_type' => 'request_type',
|
||||
'status' => 'status',
|
||||
'remarks' => 'remarks',
|
||||
'status' => 'status',
|
||||
'remarks' => 'remarks',
|
||||
];
|
||||
|
||||
$dbColumn = $columnMap[$column] ?? $column;
|
||||
@@ -430,6 +618,7 @@ use ZipArchive;
|
||||
public function sendEmail($id)
|
||||
{
|
||||
$statement = PrintStatementLog::findOrFail($id);
|
||||
|
||||
// Check if statement has email
|
||||
if (empty($statement->email)) {
|
||||
return redirect()->back()->with('error', 'No email address provided for this statement.');
|
||||
@@ -442,7 +631,7 @@ use ZipArchive;
|
||||
|
||||
try {
|
||||
$disk = Storage::disk('sftpStatement');
|
||||
$filePath = "{$statement->period_from}/Print/{$statement->branch_code}/{$statement->account_number}.pdf";
|
||||
$filePath = "{$statement->period_from}/{$statement->branch_code}/{$statement->account_number}_{$statement->period_from}.pdf";
|
||||
|
||||
if ($statement->is_period_range && $statement->period_to) {
|
||||
$periodFrom = Carbon::createFromFormat('Ym', $statement->period_from);
|
||||
@@ -454,7 +643,7 @@ use ZipArchive;
|
||||
|
||||
for ($period = clone $periodFrom; $period->lte($periodTo); $period->addMonth()) {
|
||||
$periodFormatted = $period->format('Ym');
|
||||
$periodPath = $periodFormatted . "/Print/{$statement->branch_code}/{$statement->account_number}.pdf";
|
||||
$periodPath = $periodFormatted . "/{$statement->branch_code}/{$statement->account_number}_{$periodFormatted}.pdf";
|
||||
|
||||
if ($disk->exists($periodPath)) {
|
||||
$availablePeriods[] = $periodFormatted;
|
||||
@@ -479,7 +668,7 @@ use ZipArchive;
|
||||
if ($zip->open($zipFilePath, ZipArchive::CREATE | ZipArchive::OVERWRITE) === true) {
|
||||
// Add each available statement to the zip
|
||||
foreach ($availablePeriods as $period) {
|
||||
$filePath = "{$period}/Print/{$statement->branch_code}/{$statement->account_number}.pdf";
|
||||
$filePath = "{$period}/{$statement->branch_code}/{$statement->account_number}_{$statement->period_from}.pdf";
|
||||
$localFilePath = storage_path("app/temp/{$statement->account_number}_{$period}.pdf");
|
||||
|
||||
// Download the file from SFTP to local storage temporarily
|
||||
@@ -545,8 +734,8 @@ use ZipArchive;
|
||||
|
||||
Log::info('Statement email sent successfully', [
|
||||
'statement_id' => $statement->id,
|
||||
'email' => $statement->email,
|
||||
'user_id' => Auth::id()
|
||||
'email' => $statement->email,
|
||||
'user_id' => Auth::id()
|
||||
]);
|
||||
|
||||
DB::commit();
|
||||
|
||||
Reference in New Issue
Block a user