h-1.flutter.4/@workspace/lib/pdf_templates/estimate_template.dart
joe 9cec464868 feat: 各画面の AppBar に画面 ID を追加
- estimate_screen.dart: /S1. 見積入力
- invoice_screen.dart: /S2. 請求書入力
- order_screen.dart: /S3. 受発注入力
- sales_return_screen.dart: /S5. 売上返品入力
- sales_screen.dart: /S4. 売上入力(レジ)
- product_master_screen.dart: /M1. 商品マスタ
- customer_master_screen.dart: /M2. 得意先マスタ
- supplier_master_screen.dart: /M3. 仕入先マスタ
- warehouse_master_screen.dart: /M4. 倉庫マスタ
- employee_master_screen.dart: /M5. 担当者マスタ

README.md にも画面 ID マッピングを明記
2026-03-10 16:33:07 +09:00

103 lines
No EOL
3.5 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:printing/printing.dart';
/// 見積書 WidgetPrinting で PDF 出力用)
class EstimateWidget extends StatelessWidget {
final String companyName;
final String companyAddress;
final String companyTel;
final String customerName;
final DateTime estimateDate;
final double totalAmount;
final List<Map<String, dynamic>> items;
const EstimateWidget({
super.key,
required this.companyName,
required this.companyAddress,
required this.companyTel,
required this.customerName,
required this.estimateDate,
required this.totalAmount,
required this.items,
});
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// ヘッダー
Padding(
padding: const EdgeInsets.only(top: 48.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(companyName, style: const TextStyle(fontSize: 20)),
const SizedBox(height: 6),
Text(companyAddress, style: const TextStyle(fontSize: 10)),
Text(companyTel, style: const TextStyle(fontSize: 10)),
],
),
),
const SizedBox(height: 6),
// カスタマー情報(並列)
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('見積書', style: TextStyle(fontSize: 16)),
const SizedBox(height: 4),
Text(customerName, style: const TextStyle(fontSize: 12)),
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
const Text('日付:', style: TextStyle(fontSize: 12)),
const SizedBox(height: 2),
Text(DateFormat('yyyy/MM/dd').format(estimateDate), style: const TextStyle(fontSize: 12)),
],
),
],
),
const SizedBox(height: 6),
// アイテムリスト(スクロール不可)
SingleChildScrollView(
physics: const NeverScrollableScrollPhysics(),
child: Column(
children: [
...items.map((item) => Padding(
padding: const EdgeInsets.only(bottom: 4.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('${item['productName']} (${item['quantity']}個)', style: const TextStyle(fontSize: 10)),
Text('¥${item['totalAmount']}'.replaceAllMapped(RegExp(r'\d{1,3}(?=(\d{3})+(\$))'), (Match m) => '\${m[0]}'), style: const TextStyle(fontSize: 10)),
],
),
)),
],
),
),
// フッター(合計)
Padding(
padding: const EdgeInsets.only(top: 6.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text('合計', style: TextStyle(fontSize: 14)),
Text('¥${totalAmount}'.replaceAllMapped(RegExp(r'\d{1,3}(?=(\d{3})+(\$))'), (Match m) => '\${m[0]}'), style: const TextStyle(fontSize: 16)),
],
),
),
],
);
}
}