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

@@ -61,7 +61,7 @@ void main() {
uom: StockTransactionUomSummary(id: 3, name: 'EA'),
),
quantity: 12,
unitPrice: 0,
unitPrice: 450000,
note: '라인 비고',
),
],
@@ -151,7 +151,6 @@ void main() {
await controller.loadTemplates(force: true);
await controller.loadActionOptions(force: true);
await controller.selectApproval(sampleApproval.id!);
await Future<void>.delayed(const Duration(milliseconds: 10));
expect(controller.templates, isNotEmpty);
expect(controller.selected, isNotNull);
expect(controller.canProceedSelected, isTrue);
@@ -197,6 +196,128 @@ void main() {
expect(find.text('템플릿 적용'), findsOneWidget);
});
testWidgets('입고 결재 상세 상단 카드가 파트너와 금액을 요약한다', (tester) async {
await openDialog(tester);
final highlightCard = find.byKey(
const ValueKey('approval_transaction_highlight_card'),
);
expect(highlightCard, findsOneWidget);
expect(
find.descendant(of: highlightCard, matching: find.text('출발지')),
findsOneWidget,
);
expect(
find.descendant(of: highlightCard, matching: find.text('한빛상사')),
findsWidgets,
);
expect(
find.descendant(of: highlightCard, matching: find.text('도착지')),
findsOneWidget,
);
expect(
find.descendant(of: highlightCard, matching: find.text('1센터 (WH-001)')),
findsWidgets,
);
expect(
find.descendant(of: highlightCard, matching: find.text('라인 품목')),
findsOneWidget,
);
expect(
find.descendant(of: highlightCard, matching: find.text('P-501 · 샘플 제품')),
findsOneWidget,
);
expect(
find.descendant(of: highlightCard, matching: find.text('총 금액')),
findsOneWidget,
);
expect(
find.descendant(of: highlightCard, matching: find.text('₩5,400,000')),
findsWidgets,
);
});
testWidgets('출고 결재 상세 상단 카드가 고객사 정보를 노출한다', (tester) async {
final outboundTransaction = sampleTransaction.copyWith(
type: StockTransactionType(id: 2, name: '출고'),
customers: [
StockTransactionCustomer(
id: 9002,
customer: StockTransactionCustomerSummary(
id: 4002,
code: 'C-4002',
name: '고객B',
),
),
],
);
stockRepository.detail = outboundTransaction;
await controller.selectApproval(sampleApproval.id!);
await openDialog(tester);
final highlightCard = find.byKey(
const ValueKey('approval_transaction_highlight_card'),
);
expect(highlightCard, findsOneWidget);
expect(
find.descendant(of: highlightCard, matching: find.text('출발지')),
findsOneWidget,
);
expect(
find.descendant(of: highlightCard, matching: find.text('1센터 (WH-001)')),
findsWidgets,
);
expect(
find.descendant(of: highlightCard, matching: find.text('도착지')),
findsOneWidget,
);
expect(
find.descendant(of: highlightCard, matching: find.text('고객B')),
findsOneWidget,
);
});
testWidgets('대여 결재 상세 상단 카드가 예상 반납일을 표시한다', (tester) async {
final rentalTransaction = sampleTransaction.copyWith(
type: StockTransactionType(id: 3, name: '대여'),
customers: [
StockTransactionCustomer(
id: 9003,
customer: StockTransactionCustomerSummary(
id: 4003,
code: 'C-4003',
name: '고객C',
),
),
],
);
stockRepository.detail = rentalTransaction;
await controller.selectApproval(sampleApproval.id!);
await openDialog(tester);
final highlightCard = find.byKey(
const ValueKey('approval_transaction_highlight_card'),
);
expect(highlightCard, findsOneWidget);
expect(
find.descendant(of: highlightCard, matching: find.text('도착지')),
findsOneWidget,
);
expect(
find.descendant(of: highlightCard, matching: find.text('예상 반납일')),
findsOneWidget,
);
expect(
find.descendant(
of: highlightCard,
matching: find.text('2024-01-10 00:00'),
),
findsOneWidget,
);
});
testWidgets('템플릿 적용 버튼을 누르면 assignSteps가 호출되고 성공 토스트를 노출한다', (tester) async {
await openDialog(tester);