validate([ 'account_number' => 'required|string', 'trans_reference' => 'required|string', 'period' => 'nullable|string' ]); try { // Find the statement entry $query = StmtEntry::with(['ft', 'transaction']) ->where('account_number', $request->account_number) ->where('trans_reference', $request->trans_reference); if ($request->period) { $query->where('booking_date', $request->period); } $item = $query->first(); if (!$item) { return response()->json([ 'error' => 'Statement entry not found', 'criteria' => [ 'account_number' => $request->account_number, 'trans_reference' => $request->trans_reference, 'period' => $request->period ] ], 404); } // Generate narrative using the same method from ExportStatementJob $narrative = $this->generateNarrative($item); // Format dates $transactionDate = $this->formatTransactionDate($item); $actualDate = $this->formatActualDate($item); return response()->json([ 'statement_entry' => [ 'account_number' => $item->account_number, 'trans_reference' => $item->trans_reference, 'booking_date' => $item->booking_date, 'amount_lcy' => $item->amount_lcy, 'narrative' => $item->narrative, 'date_time' => $item->date_time ], 'generated_narrative' => $narrative, 'formatted_dates' => [ 'transaction_date' => $transactionDate, 'actual_date' => $actualDate ], 'related_data' => [ 'ft' => $item->ft, 'transaction' => $item->transaction ], 'debug_info' => $this->getDebugInfo($item) ]); } catch (Exception $e) { Log::error('Debug statement error: ' . $e->getMessage()); return response()->json([ 'error' => 'An error occurred while debugging the statement', 'message' => $e->getMessage() ], 500); } } /** * List available statement entries for debugging */ public function listStatements(Request $request) { $request->validate([ 'account_number' => 'required|string', 'period' => 'nullable|string', 'limit' => 'nullable|integer|min:1|max:100' ]); $query = StmtEntry::where('account_number', $request->account_number); if ($request->period) { $query->where('booking_date', $request->period); } $statements = $query->orderBy('date_time', 'desc') ->limit($request->limit ?? 20) ->get(['account_number', 'trans_reference', 'booking_date', 'amount_lcy', 'narrative', 'date_time']); return response()->json([ 'statements' => $statements, 'count' => $statements->count() ]); } /** * Generate narrative for a statement entry (copied from ExportStatementJob) */ private function generateNarrative($item) { $narr = []; if ($item->transaction) { if ($item->transaction->stmt_narr) { $narr[] = $item->transaction->stmt_narr; } if ($item->narrative) { $narr[] = $item->narrative; } if ($item->transaction->narr_type) { $narr[] = $this->getFormatNarrative($item->transaction->narr_type, $item); } } else if ($item->narrative) { $narr[] = $item->narrative; } if ($item->ft?->recipt_no) { $narr[] = 'Receipt No: ' . $item->ft->recipt_no; } return implode(' ', array_filter($narr)); } /** * Get formatted narrative based on narrative type (copied from ExportStatementJob) */ private function getFormatNarrative($narr, $item) { $narrParam = TempStmtNarrParam::where('_id', $narr)->first(); if (!$narrParam) { return ''; } $fmt = ''; if ($narrParam->_id == 'FTIN') { $fmt = 'FT.IN'; } else if ($narrParam->_id == 'FTOUT') { $fmt = 'FT.OUT'; } else if ($narrParam->_id == 'TTTRFOUT') { $fmt = 'TT.O.TRF'; } else if ($narrParam->_id == 'TTTRFIN') { $fmt = 'TT.I.TRF'; } else if ($narrParam->_id == 'APITRX'){ $fmt = 'API.TSEL'; } else if ($narrParam->_id == 'ONUSCR'){ $fmt = 'ONUS.CR'; } else if ($narrParam->_id == 'ONUSDR'){ $fmt = 'ONUS.DR'; }else { $fmt = $narrParam->_id; } $narrFormat = TempStmtNarrFormat::where('_id', $fmt)->first(); if (!$narrFormat) { return ''; } // Get the format string from the database $formatString = $narrFormat->text_data ?? ''; // Parse the format string // Split by the separator ']' $parts = explode(']', $formatString); $result = ''; foreach ($parts as $index => $part) { if (empty($part)) { continue; } if ($index === 0) { // For the first part, take only what's before the '!' $splitPart = explode('!', $part); if (count($splitPart) > 0) { // Remove quotes, backslashes, and other escape characters $cleanPart = trim($splitPart[0]).' '; // Remove quotes at the beginning and end $cleanPart = preg_replace('/^["\'\\\\\\\]+|["\'\\\\\\\]+$/', '', $cleanPart); // Remove any remaining backslashes $cleanPart = str_replace('\\', '', $cleanPart); // Remove any remaining quotes $cleanPart = str_replace('"', '', $cleanPart); $result .= $cleanPart; } } else { // For other parts, these are field placeholders $fieldName = strtolower(str_replace('.', '_', $part)); // Get the corresponding parameter value from narrParam $paramValue = null; // Check if the field exists as a property in narrParam if (property_exists($narrParam, $fieldName)) { $paramValue = $narrParam->$fieldName; } else if (isset($narrParam->$fieldName)) { $paramValue = $narrParam->$fieldName; } // If we found a value, add it to the result if ($paramValue !== null) { $result .= $paramValue; } else { // If no value found, try to use the original field name as a fallback if ($fieldName !== 'recipt_no') { $prefix = substr($item->trans_reference ?? '', 0, 2); $relationMap = [ 'FT' => 'ft', 'TT' => 'tt', 'DC' => 'dc', 'AA' => 'aa' ]; if (isset($relationMap[$prefix])) { $relation = $relationMap[$prefix]; $result .= ($item->$relation?->$fieldName ?? '') . ' '; } } } } } return str_replace('', ' ', $result); } /** * Format transaction date (copied from ExportStatementJob) */ private function formatTransactionDate($item) { try { $prefix = substr($item->trans_reference ?? '', 0, 2); $relationMap = [ 'FT' => 'ft', 'TT' => 'tt', 'DC' => 'dc', 'AA' => 'aa' ]; $datetime = $item->date_time; if (isset($relationMap[$prefix])) { $relation = $relationMap[$prefix]; $datetime = $item->$relation?->date_time ?? $datetime; } return Carbon::createFromFormat( 'YmdHi', $item->booking_date . substr($datetime, 6, 4) )->format('d/m/Y H:i'); } catch (Exception $e) { Log::warning("Error formatting transaction date: " . $e->getMessage()); return Carbon::now()->format('d/m/Y H:i'); } } /** * Format actual date (copied from ExportStatementJob) */ private function formatActualDate($item) { try { $prefix = substr($item->trans_reference ?? '', 0, 2); $relationMap = [ 'FT' => 'ft', 'TT' => 'tt', 'DC' => 'dc', 'AA' => 'aa' ]; $datetime = $item->date_time; if (isset($relationMap[$prefix])) { $relation = $relationMap[$prefix]; $datetime = $item->$relation?->date_time ?? $datetime; } return Carbon::createFromFormat( 'ymdHi', $datetime )->format('d/m/Y H:i'); } catch (Exception $e) { Log::warning("Error formatting actual date: " . $e->getMessage()); return Carbon::now()->format('d/m/Y H:i'); } } /** * Get debug information about the statement entry */ private function getDebugInfo($item) { $prefix = substr($item->trans_reference ?? '', 0, 2); $debugInfo = [ 'transaction_prefix' => $prefix, 'has_transaction' => !is_null($item->transaction), 'has_ft' => !is_null($item->ft), 'narrative_components' => [] ]; if ($item->transaction) { $debugInfo['transaction_data'] = [ 'stmt_narr' => $item->transaction->stmt_narr, 'narr_type' => $item->transaction->narr_type ]; if ($item->transaction->narr_type) { $narrParam = TempStmtNarrParam::where('_id', $item->transaction->narr_type)->first(); $debugInfo['narr_param'] = $narrParam; if ($narrParam) { $fmt = $this->getNarrativeFormat($narrParam->_id); $narrFormat = TempStmtNarrFormat::where('_id', $fmt)->first(); $debugInfo['narr_format'] = $narrFormat; } } } return $debugInfo; } /** * Get narrative format mapping */ private function getNarrativeFormat($narrId) { $mapping = [ 'FTIN' => 'FT.IN', 'FTOUT' => 'FT.OUT', 'TTTRFOUT' => 'TT.O.TRF', 'TTTRFIN' => 'TT.I.TRF', 'APITRX' => 'API.TSEL', 'ONUSCR' => 'ONUS.CR', 'ONUSDR' => 'ONUS.DR' ]; return $mapping[$narrId] ?? $narrId; } }