feat(approvals): 결재 상세 전표 카드 개편

- 상단 요약부를 전용 Highlight 카드로 교체하고 출발지/도착지 및 라인 품목 정보를 한 화면에서 제공
- 결재 상세 다이얼로그에 통화 포매터를 연결하고 새 카드 위젯을 포함해 금액·수량을 명시적으로 표현
- 입고/출고/대여 별 라우팅/품목 정보를 검증하는 위젯 테스트를 추가해 회귀 안정성을 확보
This commit is contained in:
JiWoong Sul
2025-11-14 15:53:21 +09:00
parent 6d09e72142
commit 046b27a51a
3 changed files with 627 additions and 17 deletions

View File

@@ -11,6 +11,7 @@ import '../../../../widgets/components/superport_detail_dialog.dart';
import '../../domain/entities/approval.dart';
import '../../domain/entities/approval_template.dart';
import '../../presentation/controllers/approval_controller.dart';
import '../widgets/approval_transaction_highlight_card.dart';
import '../../../inventory/transactions/domain/entities/stock_transaction.dart';
/// 결재 상세 다이얼로그를 표시한다.
@@ -89,6 +90,11 @@ class ApprovalDetailDialogView extends StatefulWidget {
class _ApprovalDetailDialogViewState extends State<ApprovalDetailDialogView> {
int? _selectedTemplateId;
late final intl.NumberFormat _currencyFormatter = intl.NumberFormat.currency(
locale: 'ko_KR',
symbol: '',
decimalDigits: 0,
);
@override
void initState() {
@@ -441,23 +447,38 @@ class _ApprovalDetailDialogViewState extends State<ApprovalDetailDialogView> {
);
}
final highlightCard =
(isTransactionLoading ||
transaction != null ||
transactionError != null)
? ApprovalTransactionHighlightCard(
key: const ValueKey('approval_transaction_highlight_card'),
transaction: transaction,
isLoading: isTransactionLoading,
errorMessage: transactionError,
currencyFormatter: _currencyFormatter,
dateFormat: widget.dateFormat,
)
: null;
final summaryChildren = <Widget>[
if (highlightCard != null) ...[
highlightCard,
const SizedBox(height: 16),
],
Text('결재번호 ${approval.approvalNo}', style: theme.textTheme.h4),
const SizedBox(height: 4),
Text('트랜잭션 ${approval.transactionNo}', style: theme.textTheme.muted),
if (transaction != null) ...[
const SizedBox(height: 2),
Text(
'${transaction.type.name} · ${transaction.warehouse.name}',
style: theme.textTheme.small,
),
],
];
final summary = Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('결재번호 ${approval.approvalNo}', style: theme.textTheme.h4),
const SizedBox(height: 4),
Text(
'트랜잭션 ${approval.transactionNo}',
style: theme.textTheme.muted,
),
if (transaction != null) ...[
const SizedBox(height: 2),
Text(
'${transaction.type.name} · ${transaction.warehouse.name}',
style: theme.textTheme.small,
),
],
],
children: summaryChildren,
);
final summaryBadges = _buildSummaryBadges(approval, transaction);
final metadata = _buildMetadata(