inv/gemi_invoice/lib/screens/company_editor_screen.dart
2026-02-01 12:12:35 +09:00

206 lines
8.2 KiB
Dart

// lib/screens/company_editor_screen.dart
import 'package:flutter/material.dart';
import 'package:uuid/uuid.dart';
import '../models/company_model.dart';
import '../services/master_repository.dart';
/// 自社情報を編集・保存するための画面
class CompanyEditorScreen extends StatefulWidget {
const CompanyEditorScreen({super.key});
@override
State<CompanyEditorScreen> createState() => _CompanyEditorScreenState();
}
class _CompanyEditorScreenState extends State<CompanyEditorScreen> {
final _repository = MasterRepository();
final _formKey = GlobalKey<FormState>(); // フォームのバリデーション用
late Company _company;
late TextEditingController _formalNameController;
late TextEditingController _representativeController;
late TextEditingController _zipCodeController;
late TextEditingController _addressController;
late TextEditingController _telController;
late TextEditingController _faxController;
late TextEditingController _emailController;
late TextEditingController _websiteController;
late TextEditingController _registrationNumberController;
late TextEditingController _notesController;
bool _isLoading = true;
@override
void initState() {
super.initState();
_loadCompanyInfo();
}
Future<void> _loadCompanyInfo() async {
setState(() => _isLoading = true);
_company = await _repository.loadCompany();
_formalNameController = TextEditingController(text: _company.formalName);
_representativeController = TextEditingController(text: _company.representative);
_zipCodeController = TextEditingController(text: _company.zipCode);
_addressController = TextEditingController(text: _company.address);
_telController = TextEditingController(text: _company.tel);
_faxController = TextEditingController(text: _company.fax);
_emailController = TextEditingController(text: _company.email);
_websiteController = TextEditingController(text: _company.website);
_registrationNumberController = TextEditingController(text: _company.registrationNumber);
_notesController = TextEditingController(text: _company.notes);
setState(() => _isLoading = false);
}
Future<void> _saveCompanyInfo() async {
if (!_formKey.currentState!.validate()) {
return;
}
final updatedCompany = _company.copyWith(
formalName: _formalNameController.text.trim(),
representative: _representativeController.text.trim(),
zipCode: _zipCodeController.text.trim(),
address: _addressController.text.trim(),
tel: _telController.text.trim(),
fax: _faxController.text.trim(),
email: _emailController.text.trim(),
website: _websiteController.text.trim(),
registrationNumber: _registrationNumberController.text.trim(),
notes: _notesController.text.trim(),
);
await _repository.saveCompany(updatedCompany);
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('自社情報を保存しました。')),
);
Navigator.pop(context); // 編集画面を閉じる
}
}
@override
void dispose() {
_formalNameController.dispose();
_representativeController.dispose();
_zipCodeController.dispose();
_addressController.dispose();
_telController.dispose();
_faxController.dispose();
_emailController.dispose();
_websiteController.dispose();
_registrationNumberController.dispose();
_notesController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("自社情報編集"),
backgroundColor: Colors.blueGrey,
foregroundColor: Colors.white,
actions: [
IconButton(
icon: const Icon(Icons.save),
onPressed: _saveCompanyInfo,
tooltip: "保存",
),
],
),
body: _isLoading
? const Center(child: CircularProgressIndicator())
: Form(
key: _formKey,
child: SingleChildScrollView(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextFormField(
controller: _formalNameController,
decoration: const InputDecoration(labelText: "正式名称 (必須)", border: OutlineInputBorder()),
validator: (value) {
if (value == null || value.isEmpty) {
return '正式名称は必須です';
}
return null;
},
),
const SizedBox(height: 16),
TextFormField(
controller: _representativeController,
decoration: const InputDecoration(labelText: "代表者名", border: OutlineInputBorder()),
),
const SizedBox(height: 16),
TextFormField(
controller: _zipCodeController,
decoration: const InputDecoration(labelText: "郵便番号", border: OutlineInputBorder()),
keyboardType: TextInputType.text,
),
const SizedBox(height: 16),
TextFormField(
controller: _addressController,
decoration: const InputDecoration(labelText: "住所", border: OutlineInputBorder()),
maxLines: 2,
),
const SizedBox(height: 16),
TextFormField(
controller: _telController,
decoration: const InputDecoration(labelText: "電話番号", border: OutlineInputBorder()),
keyboardType: TextInputType.phone,
),
const SizedBox(height: 16),
TextFormField(
controller: _faxController,
decoration: const InputDecoration(labelText: "FAX番号", border: OutlineInputBorder()),
keyboardType: TextInputType.phone,
),
const SizedBox(height: 16),
TextFormField(
controller: _emailController,
decoration: const InputDecoration(labelText: "メールアドレス", border: OutlineInputBorder()),
keyboardType: TextInputType.emailAddress,
),
const SizedBox(height: 16),
TextFormField(
controller: _websiteController,
decoration: const InputDecoration(labelText: "ウェブサイト", border: OutlineInputBorder()),
keyboardType: TextInputType.url,
),
const SizedBox(height: 16),
TextFormField(
controller: _registrationNumberController,
decoration: const InputDecoration(labelText: "登録番号 (インボイス制度対応)", border: OutlineInputBorder()),
),
const SizedBox(height: 16),
TextFormField(
controller: _notesController,
decoration: const InputDecoration(labelText: "備考", border: OutlineInputBorder()),
maxLines: 3,
),
const SizedBox(height: 32),
SizedBox(
width: double.infinity,
child: ElevatedButton.icon(
onPressed: _saveCompanyInfo,
icon: const Icon(Icons.save),
label: const Text("自社情報を保存"),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.indigo,
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 12),
),
),
),
],
),
),
),
);
}
}