feat: Implement invoice editing, add company registration number to model and PDF, and refine PDF filename generation.

This commit is contained in:
joe 2026-02-15 00:47:04 +09:00
parent 6643aa4157
commit b11ae890ce
10 changed files with 364 additions and 96 deletions

View file

@ -1,62 +1,83 @@
Resolving dependencies...
Downloading packages...
geolocator 13.0.4 (14.0.2 available)
geolocator_android 4.6.2 (5.0.2 available)
image 4.5.4 (4.7.2 available)
meta 1.17.0 (1.18.1 available)
petitparser 7.0.1 (7.0.2 available)
Got dependencies!
5 packages have newer versions incompatible with dependency constraints.
Try `flutter pub outdated` for more information.
Analyzing gemi_invoice_backup2...
warning • The value of the field '_lastGeneratedInvoice' isn't used • lib/main.dart:43:12 • unused_field
error • The body might complete normally, causing 'null' to be returned, but the return type, 'Widget', is a potentially non-nullable type • lib/main.dart:61:10 • body_might_complete_normally
warning • The label 'appBar' isn't used • lib/main.dart:62:7 • unused_label
error • Expected to find ';' • lib/main.dart:65:7 • expected_token
error • Expected an identifier • lib/main.dart:65:8 • missing_identifier
error • Unexpected text ';' • lib/main.dart:65:8 • unexpected_token
warning • The label 'drawer' isn't used • lib/main.dart:66:7 • unused_label
error • Expected to find ';' • lib/main.dart:92:7 • expected_token
error • Expected an identifier • lib/main.dart:92:8 • missing_identifier
error • Unexpected text ';' • lib/main.dart:92:8 • unexpected_token
warning • The label 'body' isn't used • lib/main.dart:94:7 • unused_label
error • Expected to find ';' • lib/main.dart:106:7 • expected_token
error • Expected an identifier • lib/main.dart:106:8 • missing_identifier
error • Expected to find ';' • lib/main.dart:106:8 • expected_token
error • Unexpected text ';' • lib/main.dart:106:8 • unexpected_token
error • Expected an identifier • lib/main.dart:107:5 • missing_identifier
error • Unexpected text ';' • lib/main.dart:107:5 • unexpected_token
info • Unnecessary empty statement • lib/main.dart:107:6 • empty_statements
info • The imported package 'uuid' isn't a dependency of the importing package • lib/models/customer_model.dart:1:8 • depend_on_referenced_packages
warning • Unused import: 'package:uuid/uuid.dart' • lib/models/customer_model.dart:1:8 • unused_import
error • The named parameter 'unitPrice' is required, but there's no corresponding argument • lib/models/invoice_models.dart:30:12 • missing_required_argument
error • The named parameter 'unit_price' isn't defined • lib/models/invoice_models.dart:34:7 • undefined_named_parameter
warning • The value of the local variable 'amountFormatter' isn't used • lib/models/invoice_models.dart:88:11 • unused_local_variable
info • The imported package 'uuid' isn't a dependency of the importing package • lib/screens/customer_picker_modal.dart:3:8 • depend_on_referenced_packages
error • Undefined class 'Customer' • lib/screens/customer_picker_modal.dart:8:18 • undefined_class
info • Parameter 'key' could be a super parameter • lib/screens/customer_picker_modal.dart:10:9 • use_super_parameters
error • The name 'Customer' isn't a type, so it can't be used as a type argument • lib/screens/customer_picker_modal.dart:22:8 • non_type_as_type_argument
error • The name 'Customer' isn't a type, so it can't be used as a type argument • lib/screens/customer_picker_modal.dart:23:8 • non_type_as_type_argument
error • The property 'formalName' can't be unconditionally accessed because the receiver can be 'null' • lib/screens/customer_picker_modal.dart:47:25 • unchecked_use_of_nullable_value
error • The property 'displayName' can't be unconditionally accessed because the receiver can be 'null' • lib/screens/customer_picker_modal.dart:48:22 • unchecked_use_of_nullable_value
info • Don't use 'BuildContext's across async gaps • lib/screens/customer_picker_modal.dart:77:28 • use_build_context_synchronously
error • Undefined class 'Customer' • lib/screens/customer_picker_modal.dart:87:5 • undefined_class
error • The method 'Customer' isn't defined for the type '_CustomerPickerModalState' • lib/screens/customer_picker_modal.dart:141:19 • undefined_method
info • Don't use 'BuildContext's across async gaps • lib/screens/customer_picker_modal.dart:150:29 • use_build_context_synchronously
error • Undefined class 'Customer' • lib/screens/customer_picker_modal.dart:164:23 • undefined_class
info • Don't use 'BuildContext's across async gaps • lib/screens/customer_picker_modal.dart:175:29 • use_build_context_synchronously
warning • Unused import: 'dart:io' • lib/screens/invoice_detail_page.dart:1:8 • unused_import
warning • Unused import: '../models/customer_model.dart' • lib/screens/invoice_detail_page.dart:7:8 • unused_import
info • Parameter 'key' could be a super parameter • lib/screens/invoice_detail_page.dart:16:9 • use_super_parameters
info • Don't use 'BuildContext's across async gaps • lib/screens/invoice_detail_page.dart:120:28 • use_build_context_synchronously
info • 'Share' is deprecated and shouldn't be used. Use SharePlus instead • lib/screens/invoice_detail_page.dart:128:5 • deprecated_member_use
info • 'share' is deprecated and shouldn't be used. Use SharePlus.instance.share() instead • lib/screens/invoice_detail_page.dart:128:11 • deprecated_member_use
info • Use a 'SizedBox' to add whitespace to a layout • lib/screens/invoice_detail_page.dart:283:14 • sized_box_for_whitespace
info • 'Share' is deprecated and shouldn't be used. Use SharePlus instead • lib/screens/invoice_detail_page.dart:327:43 • deprecated_member_use
info • 'shareXFiles' is deprecated and shouldn't be used. Use SharePlus.instance.share() instead • lib/screens/invoice_detail_page.dart:327:49 • deprecated_member_use
warning • Unused import: '../models/customer_model.dart' • lib/screens/invoice_history_screen.dart:4:8 • unused_import
info • Parameter 'key' could be a super parameter • lib/screens/invoice_history_screen.dart:10:9 • use_super_parameters
info • The imported package 'uuid' isn't a dependency of the importing package • lib/screens/invoice_input_screen.dart:2:8 • depend_on_referenced_packages
info • Parameter 'key' could be a super parameter • lib/screens/invoice_input_screen.dart:14:9 • use_super_parameters
info • The private field _customerBuffer could be 'final' • lib/screens/invoice_input_screen.dart:29:18 • prefer_final_fields
warning • The value of the field '_customerBuffer' isn't used • lib/screens/invoice_input_screen.dart:29:18 • unused_field
error • A value of type 'Object?' can't be assigned to a variable of type 'Customer?' • lib/screens/invoice_input_screen.dart:87:35 • invalid_assignment
error • The property 'formalName' can't be unconditionally accessed because the receiver can be 'null' • lib/screens/invoice_input_screen.dart:88:49 • unchecked_use_of_nullable_value
error • The property 'formalName' can't be unconditionally accessed because the receiver can be 'null' • lib/screens/invoice_input_screen.dart:89:38 • unchecked_use_of_nullable_value
info • Parameter 'key' could be a super parameter • lib/screens/product_picker_modal.dart:8:9 • use_super_parameters
info • 'desiredAccuracy' is deprecated and shouldn't be used. use settings parameter with AndroidSettings, AppleSettings, WebSettings, or LocationSettings • lib/services/location_service.dart:28:9 • deprecated_member_use
info • 'timeLimit' is deprecated and shouldn't be used. use settings parameter with AndroidSettings, AppleSettings, WebSettings, or LocationSettings • lib/services/location_service.dart:29:9 • deprecated_member_use
info • The import of 'dart:typed_data' is unnecessary because all of the used elements are also provided by the import of 'package:flutter/services.dart' • lib/services/pdf_generator.dart:2:8 • unnecessary_import
info • Parameter 'key' could be a super parameter • lib/screens/activity_log_screen.dart:7:9 • use_super_parameters
info • 'withOpacity' is deprecated and shouldn't be used. Use .withValues() to avoid precision loss • lib/screens/activity_log_screen.dart:94:34 • deprecated_member_use
info • Parameter 'key' could be a super parameter • lib/screens/barcode_scanner_screen.dart:5:9 • use_super_parameters
info • Parameter 'key' could be a super parameter • lib/screens/company_info_screen.dart:8:9 • use_super_parameters
info • Don't use 'BuildContext's across async gaps • lib/screens/company_info_screen.dart:63:26 • use_build_context_synchronously
info • Don't use 'BuildContext's across async gaps • lib/screens/company_info_screen.dart:64:19 • use_build_context_synchronously
info • Parameter 'key' could be a super parameter • lib/screens/customer_master_screen.dart:7:9 • use_super_parameters
info • 'value' is deprecated and shouldn't be used. Use initialValue instead. This will set the initial value for the form field. This feature was deprecated after v3.33.0-1.0.pre • lib/screens/customer_master_screen.dart:60:19 • deprecated_member_use
info • The 'child' argument should be last in widget constructor invocations • lib/screens/customer_master_screen.dart:164:9 • sort_child_properties_last
info • Parameter 'key' could be a super parameter • lib/screens/customer_picker_modal.dart:11:9 • use_super_parameters
info • The private field _searchQuery could be 'final' • lib/screens/customer_picker_modal.dart:22:10 • prefer_final_fields
warning • The value of the field '_searchQuery' isn't used • lib/screens/customer_picker_modal.dart:22:10 • unused_field
info • The private field _allCustomers could be 'final' • lib/screens/customer_picker_modal.dart:23:18 • prefer_final_fields
warning • The value of the field '_allCustomers' isn't used • lib/screens/customer_picker_modal.dart:23:18 • unused_field
info • Don't use 'BuildContext's across async gaps • lib/screens/customer_picker_modal.dart:67:28 • use_build_context_synchronously
info • Don't use 'BuildContext's across async gaps • lib/screens/customer_picker_modal.dart:140:29 • use_build_context_synchronously
info • Don't use 'BuildContext's across async gaps • lib/screens/customer_picker_modal.dart:165:29 • use_build_context_synchronously
info • Parameter 'key' could be a super parameter • lib/screens/gps_history_screen.dart:6:9 • use_super_parameters
info • Parameter 'key' could be a super parameter • lib/screens/invoice_detail_page.dart:19:9 • use_super_parameters
info • Don't use 'BuildContext's across async gaps • lib/screens/invoice_detail_page.dart:136:28 • use_build_context_synchronously
info • 'Share' is deprecated and shouldn't be used. Use SharePlus instead • lib/screens/invoice_detail_page.dart:144:5 • deprecated_member_use
info • 'share' is deprecated and shouldn't be used. Use SharePlus.instance.share() instead • lib/screens/invoice_detail_page.dart:144:11 • deprecated_member_use
info • Don't use 'BuildContext's across async gaps • lib/screens/invoice_detail_page.dart:160:9 • use_build_context_synchronously
warning • Dead code • lib/screens/invoice_detail_page.dart:170:47 • dead_code
warning • The left operand can't be null, so the right operand is never executed • lib/screens/invoice_detail_page.dart:170:50 • dead_null_aware_expression
warning • The left operand can't be null, so the right operand is never executed • lib/screens/invoice_detail_page.dart:171:58 • dead_null_aware_expression
warning • The '!' will have no effect because the receiver can't be null • lib/screens/invoice_detail_page.dart:180:65 • unnecessary_non_null_assertion
error • The method 'InvoiceInputForm' isn't defined for the type '_InvoiceDetailPageState' • lib/screens/invoice_detail_page.dart:230:45 • undefined_method
error • 1 positional argument expected by 'getAllInvoices', but 0 found • lib/screens/invoice_detail_page.dart:240:62 • not_enough_positional_arguments
warning • The value of the local variable 'dateFormatter' isn't used • lib/screens/invoice_detail_page.dart:307:11 • unused_local_variable
info • 'withOpacity' is deprecated and shouldn't be used. Use .withValues() to avoid precision loss • lib/screens/invoice_detail_page.dart:346:114 • deprecated_member_use
info • 'withOpacity' is deprecated and shouldn't be used. Use .withValues() to avoid precision loss • lib/screens/invoice_detail_page.dart:376:84 • deprecated_member_use
info • 'Share' is deprecated and shouldn't be used. Use SharePlus instead • lib/screens/invoice_detail_page.dart:614:13 • deprecated_member_use
info • 'shareXFiles' is deprecated and shouldn't be used. Use SharePlus.instance.share() instead • lib/screens/invoice_detail_page.dart:614:19 • deprecated_member_use
warning • The declaration '_SummaryRow' isn't referenced • lib/screens/invoice_detail_page.dart:661:7 • unused_element
warning • A value for optional parameter 'isBold' isn't ever given • lib/screens/invoice_detail_page.dart:664:51 • unused_element_parameter
info • Parameter 'key' could be a super parameter • lib/screens/invoice_history_screen.dart:15:9 • use_super_parameters
warning • The value of the field '_isLoading' isn't used • lib/screens/invoice_history_screen.dart:26:8 • unused_field
warning • The value of the local variable 'amountFormatter' isn't used • lib/screens/invoice_history_screen.dart:97:11 • unused_local_variable
warning • The value of the local variable 'dateFormatter' isn't used • lib/screens/invoice_history_screen.dart:98:11 • unused_local_variable
error • Undefined name 'children' • lib/screens/invoice_history_screen.dart:235:9 • undefined_identifier
error • Expected to find ')' • lib/screens/invoice_history_screen.dart:235:17 • expected_token
error • Expected to find ']' • lib/screens/invoice_history_screen.dart:235:17 • expected_token
warning • Unused import: 'package:uuid/uuid.dart' • lib/screens/invoice_input_screen.dart:2:8 • unused_import
info • Parameter 'key' could be a super parameter • lib/screens/invoice_input_screen.dart:20:9 • use_super_parameters
warning • The value of the field '_status' isn't used • lib/screens/invoice_input_screen.dart:41:10 • unused_field
info • The private field _signaturePath could be 'final' • lib/screens/invoice_input_screen.dart:44:17 • prefer_final_fields
info • Don't use 'BuildContext's across async gaps • lib/screens/invoice_input_screen.dart:137:30 • use_build_context_synchronously
info • Don't use 'BuildContext's across async gaps • lib/screens/invoice_input_screen.dart:141:28 • use_build_context_synchronously
info • Don't use 'BuildContext's across async gaps • lib/screens/invoice_input_screen.dart:142:21 • use_build_context_synchronously
error • The method 'copyWith' isn't defined for the type 'InvoiceItem' • lib/screens/invoice_input_screen.dart:393:50 • undefined_method
info • 'activeColor' is deprecated and shouldn't be used. Use activeThumbColor instead. This feature was deprecated after v3.31.0-2.0.pre • lib/screens/invoice_input_screen.dart:600:13 • deprecated_member_use
info • 'withOpacity' is deprecated and shouldn't be used. Use .withValues() to avoid precision loss • lib/screens/invoice_input_screen.dart:619:51 • deprecated_member_use
warning • Unused import: 'package:path_provider/path_provider.dart' • lib/screens/management_screen.dart:6:8 • unused_import
info • Parameter 'key' could be a super parameter • lib/screens/management_screen.dart:16:9 • use_super_parameters
info • 'Share' is deprecated and shouldn't be used. Use SharePlus instead • lib/screens/management_screen.dart:147:11 • deprecated_member_use
info • 'share' is deprecated and shouldn't be used. Use SharePlus.instance.share() instead • lib/screens/management_screen.dart:147:17 • deprecated_member_use
info • 'Share' is deprecated and shouldn't be used. Use SharePlus instead • lib/screens/management_screen.dart:154:13 • deprecated_member_use
info • 'shareXFiles' is deprecated and shouldn't be used. Use SharePlus.instance.share() instead • lib/screens/management_screen.dart:154:19 • deprecated_member_use
info • Parameter 'key' could be a super parameter • lib/screens/product_master_screen.dart:8:9 • use_super_parameters
info • Don't use 'BuildContext's across async gaps • lib/screens/product_master_screen.dart:182:55 • use_build_context_synchronously
info • The 'child' argument should be last in widget constructor invocations • lib/screens/product_master_screen.dart:199:9 • sort_child_properties_last
info • Parameter 'key' could be a super parameter • lib/screens/product_picker_modal.dart:11:9 • use_super_parameters
info • Parameter 'key' could be a super parameter • lib/screens/sales_report_screen.dart:6:9 • use_super_parameters
warning • Unused import: 'package:crypto/crypto.dart' • lib/services/pdf_generator.dart:7:8 • unused_import
info • Unnecessary braces in a string interpolation • lib/services/pdf_generator.dart:274:24 • unnecessary_brace_in_string_interps
info • Unnecessary braces in a string interpolation • lib/services/pdf_generator.dart:274:63 • unnecessary_brace_in_string_interps
info • Unnecessary braces in a string interpolation • lib/services/pdf_generator.dart:274:96 • unnecessary_brace_in_string_interps
info • Use the null-aware marker '?' rather than a null check via an 'if' • lib/services/pdf_generator.dart:346:13 • use_null_aware_elements
info • Parameter 'key' could be a super parameter • lib/widgets/slide_to_unlock.dart:8:9 • use_super_parameters
58 issues found. (ran in 23.0s)

76
analyze_output_v2.txt Normal file
View file

@ -0,0 +1,76 @@
Resolving dependencies...
Downloading packages...
geolocator 13.0.4 (14.0.2 available)
geolocator_android 4.6.2 (5.0.2 available)
image 4.5.4 (4.7.2 available)
meta 1.17.0 (1.18.1 available)
petitparser 7.0.1 (7.0.2 available)
Got dependencies!
5 packages have newer versions incompatible with dependency constraints.
Try `flutter pub outdated` for more information.
Analyzing gemi_invoice_backup2...
info • Parameter 'key' could be a super parameter • lib/screens/activity_log_screen.dart:7:9 • use_super_parameters
info • 'withOpacity' is deprecated and shouldn't be used. Use .withValues() to avoid precision loss • lib/screens/activity_log_screen.dart:94:34 • deprecated_member_use
info • Parameter 'key' could be a super parameter • lib/screens/barcode_scanner_screen.dart:5:9 • use_super_parameters
info • Parameter 'key' could be a super parameter • lib/screens/company_info_screen.dart:8:9 • use_super_parameters
info • Don't use 'BuildContext's across async gaps • lib/screens/company_info_screen.dart:63:26 • use_build_context_synchronously
info • Don't use 'BuildContext's across async gaps • lib/screens/company_info_screen.dart:64:19 • use_build_context_synchronously
info • Parameter 'key' could be a super parameter • lib/screens/customer_master_screen.dart:7:9 • use_super_parameters
info • 'value' is deprecated and shouldn't be used. Use initialValue instead. This will set the initial value for the form field. This feature was deprecated after v3.33.0-1.0.pre • lib/screens/customer_master_screen.dart:60:19 • deprecated_member_use
info • The 'child' argument should be last in widget constructor invocations • lib/screens/customer_master_screen.dart:164:9 • sort_child_properties_last
info • Parameter 'key' could be a super parameter • lib/screens/customer_picker_modal.dart:11:9 • use_super_parameters
info • The private field _searchQuery could be 'final' • lib/screens/customer_picker_modal.dart:22:10 • prefer_final_fields
warning • The value of the field '_searchQuery' isn't used • lib/screens/customer_picker_modal.dart:22:10 • unused_field
info • The private field _allCustomers could be 'final' • lib/screens/customer_picker_modal.dart:23:18 • prefer_final_fields
warning • The value of the field '_allCustomers' isn't used • lib/screens/customer_picker_modal.dart:23:18 • unused_field
info • Don't use 'BuildContext's across async gaps • lib/screens/customer_picker_modal.dart:67:28 • use_build_context_synchronously
info • Don't use 'BuildContext's across async gaps • lib/screens/customer_picker_modal.dart:140:29 • use_build_context_synchronously
info • Don't use 'BuildContext's across async gaps • lib/screens/customer_picker_modal.dart:165:29 • use_build_context_synchronously
info • Parameter 'key' could be a super parameter • lib/screens/gps_history_screen.dart:6:9 • use_super_parameters
info • Parameter 'key' could be a super parameter • lib/screens/invoice_detail_page.dart:20:9 • use_super_parameters
info • Don't use 'BuildContext's across async gaps • lib/screens/invoice_detail_page.dart:137:28 • use_build_context_synchronously
info • 'Share' is deprecated and shouldn't be used. Use SharePlus instead • lib/screens/invoice_detail_page.dart:145:5 • deprecated_member_use
info • 'share' is deprecated and shouldn't be used. Use SharePlus.instance.share() instead • lib/screens/invoice_detail_page.dart:145:11 • deprecated_member_use
info • Don't use 'BuildContext's across async gaps • lib/screens/invoice_detail_page.dart:161:9 • use_build_context_synchronously
warning • Dead code • lib/screens/invoice_detail_page.dart:171:47 • dead_code
warning • The left operand can't be null, so the right operand is never executed • lib/screens/invoice_detail_page.dart:171:50 • dead_null_aware_expression
warning • The left operand can't be null, so the right operand is never executed • lib/screens/invoice_detail_page.dart:172:58 • dead_null_aware_expression
warning • The '!' will have no effect because the receiver can't be null • lib/screens/invoice_detail_page.dart:181:65 • unnecessary_non_null_assertion
warning • The value of the local variable 'dateFormatter' isn't used • lib/screens/invoice_detail_page.dart:310:11 • unused_local_variable
info • 'withOpacity' is deprecated and shouldn't be used. Use .withValues() to avoid precision loss • lib/screens/invoice_detail_page.dart:349:114 • deprecated_member_use
info • 'withOpacity' is deprecated and shouldn't be used. Use .withValues() to avoid precision loss • lib/screens/invoice_detail_page.dart:379:84 • deprecated_member_use
info • 'Share' is deprecated and shouldn't be used. Use SharePlus instead • lib/screens/invoice_detail_page.dart:617:13 • deprecated_member_use
info • 'shareXFiles' is deprecated and shouldn't be used. Use SharePlus.instance.share() instead • lib/screens/invoice_detail_page.dart:617:19 • deprecated_member_use
warning • The declaration '_SummaryRow' isn't referenced • lib/screens/invoice_detail_page.dart:664:7 • unused_element
warning • A value for optional parameter 'isBold' isn't ever given • lib/screens/invoice_detail_page.dart:667:51 • unused_element_parameter
warning • Unused import: '../models/customer_model.dart' • lib/screens/invoice_history_screen.dart:4:8 • unused_import
info • Parameter 'key' could be a super parameter • lib/screens/invoice_history_screen.dart:15:9 • use_super_parameters
warning • Unused import: 'package:uuid/uuid.dart' • lib/screens/invoice_input_screen.dart:2:8 • unused_import
info • Parameter 'key' could be a super parameter • lib/screens/invoice_input_screen.dart:20:9 • use_super_parameters
warning • The value of the field '_status' isn't used • lib/screens/invoice_input_screen.dart:41:10 • unused_field
info • The private field _signaturePath could be 'final' • lib/screens/invoice_input_screen.dart:44:17 • prefer_final_fields
info • Don't use 'BuildContext's across async gaps • lib/screens/invoice_input_screen.dart:137:30 • use_build_context_synchronously
info • Don't use 'BuildContext's across async gaps • lib/screens/invoice_input_screen.dart:141:28 • use_build_context_synchronously
info • Don't use 'BuildContext's across async gaps • lib/screens/invoice_input_screen.dart:142:21 • use_build_context_synchronously
error • The method 'copyWith' isn't defined for the type 'InvoiceItem' • lib/screens/invoice_input_screen.dart:393:50 • undefined_method
info • 'activeColor' is deprecated and shouldn't be used. Use activeThumbColor instead. This feature was deprecated after v3.31.0-2.0.pre • lib/screens/invoice_input_screen.dart:600:13 • deprecated_member_use
info • 'withOpacity' is deprecated and shouldn't be used. Use .withValues() to avoid precision loss • lib/screens/invoice_input_screen.dart:619:51 • deprecated_member_use
warning • Unused import: 'package:path_provider/path_provider.dart' • lib/screens/management_screen.dart:6:8 • unused_import
info • Parameter 'key' could be a super parameter • lib/screens/management_screen.dart:16:9 • use_super_parameters
info • 'Share' is deprecated and shouldn't be used. Use SharePlus instead • lib/screens/management_screen.dart:147:11 • deprecated_member_use
info • 'share' is deprecated and shouldn't be used. Use SharePlus.instance.share() instead • lib/screens/management_screen.dart:147:17 • deprecated_member_use
info • 'Share' is deprecated and shouldn't be used. Use SharePlus instead • lib/screens/management_screen.dart:154:13 • deprecated_member_use
info • 'shareXFiles' is deprecated and shouldn't be used. Use SharePlus.instance.share() instead • lib/screens/management_screen.dart:154:19 • deprecated_member_use
info • Parameter 'key' could be a super parameter • lib/screens/product_master_screen.dart:8:9 • use_super_parameters
info • Don't use 'BuildContext's across async gaps • lib/screens/product_master_screen.dart:182:55 • use_build_context_synchronously
info • The 'child' argument should be last in widget constructor invocations • lib/screens/product_master_screen.dart:199:9 • sort_child_properties_last
info • Parameter 'key' could be a super parameter • lib/screens/product_picker_modal.dart:11:9 • use_super_parameters
info • Parameter 'key' could be a super parameter • lib/screens/sales_report_screen.dart:6:9 • use_super_parameters
warning • Unused import: 'package:crypto/crypto.dart' • lib/services/pdf_generator.dart:7:8 • unused_import
info • Unnecessary braces in a string interpolation • lib/services/pdf_generator.dart:274:24 • unnecessary_brace_in_string_interps
info • Unnecessary braces in a string interpolation • lib/services/pdf_generator.dart:274:63 • unnecessary_brace_in_string_interps
info • Unnecessary braces in a string interpolation • lib/services/pdf_generator.dart:274:96 • unnecessary_brace_in_string_interps
info • Use the null-aware marker '?' rather than a null check via an 'if' • lib/services/pdf_generator.dart:346:13 • use_null_aware_elements
info • Parameter 'key' could be a super parameter • lib/widgets/slide_to_unlock.dart:8:9 • use_super_parameters

View file

@ -6,6 +6,7 @@ class CompanyInfo {
final double defaultTaxRate;
final String? sealPath; //
final String taxDisplayMode; // 'normal', 'hidden', 'text_only'
final String? registrationNumber; // : (T番号)
CompanyInfo({
required this.name,
@ -15,6 +16,7 @@ class CompanyInfo {
this.defaultTaxRate = 0.10,
this.sealPath,
this.taxDisplayMode = 'normal',
this.registrationNumber, //
});
Map<String, dynamic> toMap() {
@ -27,6 +29,7 @@ class CompanyInfo {
'default_tax_rate': defaultTaxRate,
'seal_path': sealPath,
'tax_display_mode': taxDisplayMode,
'registration_number': registrationNumber, //
};
}
@ -39,6 +42,7 @@ class CompanyInfo {
defaultTaxRate: map['default_tax_rate'] ?? 0.10,
sealPath: map['seal_path'],
taxDisplayMode: map['tax_display_mode'] ?? 'normal',
registrationNumber: map['registration_number'], //
);
}
@ -50,6 +54,7 @@ class CompanyInfo {
double? defaultTaxRate,
String? sealPath,
String? taxDisplayMode,
String? registrationNumber, //
}) {
return CompanyInfo(
name: name ?? this.name,
@ -59,6 +64,7 @@ class CompanyInfo {
defaultTaxRate: defaultTaxRate ?? this.defaultTaxRate,
sealPath: sealPath ?? this.sealPath,
taxDisplayMode: taxDisplayMode ?? this.taxDisplayMode,
registrationNumber: registrationNumber ?? this.registrationNumber, //
);
}
}

View file

@ -40,6 +40,22 @@ class InvoiceItem {
unitPrice: map['unit_price'],
);
}
InvoiceItem copyWith({
String? id, // Added this to be complete
String? description,
int? quantity,
int? unitPrice,
String? productId,
}) {
return InvoiceItem(
id: id ?? this.id, // Added this to be complete
description: description ?? this.description,
quantity: quantity ?? this.quantity,
unitPrice: unitPrice ?? this.unitPrice,
productId: productId ?? this.productId,
);
}
}
enum DocumentType {

View file

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'invoice_input_screen.dart'; // Add this line
import 'package:intl/intl.dart';
import 'package:share_plus/share_plus.dart';
import 'package:open_filex/open_filex.dart';
@ -220,7 +221,29 @@ class _InvoiceDetailPageState extends State<InvoiceDetailPage> {
if (!_isEditing) ...[
IconButton(icon: const Icon(Icons.grid_on), onPressed: _exportCsv, tooltip: "CSV出力"),
if (widget.isUnlocked)
IconButton(icon: const Icon(Icons.edit), onPressed: () => setState(() => _isEditing = true)),
IconButton(
icon: const Icon(Icons.edit_note), //
tooltip: "詳細編集",
onPressed: () async {
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => InvoiceInputForm(
onInvoiceGenerated: (inv, path) {
//
},
existingInvoice: _currentInvoice,
),
),
);
//
final repo = InvoiceRepository();
final customerRepo = CustomerRepository();
final customers = await customerRepo.getAllCustomers();
final updated = (await repo.getAllInvoices(customers)).firstWhere((i) => i.id == _currentInvoice.id, orElse: () => _currentInvoice);
setState(() => _currentInvoice = updated);
},
),
] else ...[
if (isDraft)
TextButton.icon(
@ -430,12 +453,14 @@ class _InvoiceDetailPageState extends State<InvoiceDetailPage> {
return Column(
children: [
_buildSummaryRow("小計", formatter.format(subtotal), textColor),
if (currentTaxRate > 0) ...[
if (_companyInfo?.taxDisplayMode == 'normal')
_buildSummaryRow("消費税 (${(currentTaxRate * 100).toInt()}%)", formatter.format(tax), textColor),
if (_companyInfo?.taxDisplayMode == 'text_only')
_buildSummaryRow("消費税", "(税別)", textColor),
],
const Divider(color: Colors.grey),
_buildSummaryRow("合計金額", "${formatter.format(total)}", textColor, isTotal: true),
_buildSummaryRow(currentTaxRate > 0 ? "合計金額 (税込)" : "合計金額", "${formatter.format(total)}", textColor, isTotal: true),
],
);
}

View file

@ -99,6 +99,7 @@ class _InvoiceHistoryScreenState extends State<InvoiceHistoryScreen> {
return Scaffold(
appBar: AppBar(
leading: const BackButton(), //
title: GestureDetector(
onLongPress: () {
Navigator.push(
@ -231,11 +232,14 @@ class _InvoiceHistoryScreenState extends State<InvoiceHistoryScreen> {
),
body: Column(
children: [
SlideToUnlock(
Padding(
padding: const EdgeInsets.all(16.0),
child: SlideToUnlock(
isLocked: !_isUnlocked,
onUnlocked: _toggleUnlock,
text: "スライドでロック解除",
),
),
Expanded(
child: _isLoading
? const Center(child: CircularProgressIndicator())
@ -251,6 +255,7 @@ class _InvoiceHistoryScreenState extends State<InvoiceHistoryScreen> {
),
)
: ListView.builder(
padding: const EdgeInsets.only(bottom: 100), // FAB考慮
itemCount: _filteredInvoices.length,
itemBuilder: (context, index) {
final invoice = _filteredInvoices[index];

View file

@ -15,10 +15,12 @@ import '../services/company_repository.dart';
class InvoiceInputForm extends StatefulWidget {
final Function(Invoice invoice, String filePath) onInvoiceGenerated;
final Invoice? existingInvoice; // :
const InvoiceInputForm({
Key? key,
required this.onInvoiceGenerated,
this.existingInvoice, //
}) : super(key: key);
@override
@ -59,7 +61,20 @@ class _InvoiceInputFormState extends State<InvoiceInputForm> {
final companyInfo = await companyRepo.getCompanyInfo();
setState(() {
_companyInfo = companyInfo;
//
if (widget.existingInvoice != null) {
final inv = widget.existingInvoice!;
_selectedCustomer = inv.customer;
_items.addAll(inv.items);
_taxRate = inv.taxRate;
_includeTax = inv.taxRate > 0;
_documentType = inv.documentType;
_selectedDate = inv.date;
_isDraft = inv.isDraft;
if (inv.subject != null) _subjectController.text = inv.subject!;
} else {
_taxRate = companyInfo.defaultTaxRate;
}
});
}
@ -98,6 +113,7 @@ class _InvoiceInputFormState extends State<InvoiceInputForm> {
}
final invoice = Invoice(
id: widget.existingInvoice?.id, // IDがあれば引き継ぐ
customer: _selectedCustomer!,
date: _selectedDate,
items: _items,
@ -180,7 +196,7 @@ class _InvoiceInputFormState extends State<InvoiceInputForm> {
backgroundColor: themeColor,
appBar: AppBar(
leading: const BackButton(),
title: Text(_isDraft ? "伝票作成 (下書きモード)" : "販売アシスト1号 V1.5.03"),
title: Text(_isDraft ? "伝票作成 (下書き)" : "販売アシスト1号 V1.5.04"),
backgroundColor: _isDraft ? Colors.black87 : Colors.blueGrey,
),
body: Column(
@ -298,7 +314,7 @@ class _InvoiceInputFormState extends State<InvoiceInputForm> {
leading: const Icon(Icons.business, color: Colors.blueGrey),
title: Text(_selectedCustomer?.formalName ?? "取引先を選択してください",
style: TextStyle(color: _selectedCustomer == null ? Colors.grey : Colors.black87, fontWeight: FontWeight.bold)),
subtitle: const Text("請求先マスターから選択"),
subtitle: const Text("顧客マスターから選択"), //
trailing: const Icon(Icons.chevron_right),
onTap: () async {
await showModalBottomSheet(
@ -352,6 +368,42 @@ class _InvoiceInputFormState extends State<InvoiceInputForm> {
),
],
),
onTap: () {
//
final descCtrl = TextEditingController(text: item.description);
final qtyCtrl = TextEditingController(text: item.quantity.toString());
final priceCtrl = TextEditingController(text: item.unitPrice.toString());
showDialog(
context: context,
builder: (context) => AlertDialog(
title: const Text("明細の編集"),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextField(controller: descCtrl, decoration: const InputDecoration(labelText: "品名 / 項目")),
TextField(controller: qtyCtrl, decoration: const InputDecoration(labelText: "数量"), keyboardType: TextInputType.number),
TextField(controller: priceCtrl, decoration: const InputDecoration(labelText: "単価"), keyboardType: TextInputType.number),
],
),
actions: [
TextButton(onPressed: () => Navigator.pop(context), child: const Text("キャンセル")),
ElevatedButton(
onPressed: () {
setState(() {
_items[idx] = item.copyWith(
description: descCtrl.text,
quantity: int.tryParse(qtyCtrl.text) ?? item.quantity,
unitPrice: int.tryParse(priceCtrl.text) ?? item.unitPrice,
);
});
Navigator.pop(context);
},
child: const Text("更新"),
),
],
),
);
},
),
);
}),
@ -370,6 +422,7 @@ class _InvoiceInputFormState extends State<InvoiceInputForm> {
const SizedBox(height: 8),
Row(
children: [
if (_includeTax) ...[
const Text("消費税: "),
ChoiceChip(
label: const Text("10%"),
@ -382,6 +435,8 @@ class _InvoiceInputFormState extends State<InvoiceInputForm> {
selected: _taxRate == 0.08,
onSelected: (val) => setState(() => _taxRate = 0.08),
),
] else
const Text("(税別設定のため設定なし)", style: TextStyle(color: Colors.grey)),
const Spacer(),
Switch(
value: _includeTax,
@ -401,13 +456,15 @@ class _InvoiceInputFormState extends State<InvoiceInputForm> {
decoration: BoxDecoration(color: Colors.indigo.shade900, borderRadius: BorderRadius.circular(12)),
child: Column(
children: [
_buildSummaryRow("小計 (税抜)", "${fmt.format(_subTotal)}", Colors.white70),
_buildSummaryRow(_includeTax ? "小計 (税抜)" : "小計", "${fmt.format(_subTotal)}", Colors.white70),
if (_includeTax) ...[
if (_companyInfo?.taxDisplayMode == 'normal')
_buildSummaryRow("消費税 (${(_taxRate * 100).toInt()}%)", "${fmt.format(_tax)}", Colors.white70),
if (_companyInfo?.taxDisplayMode == 'text_only')
_buildSummaryRow("消費税", "(税別)", Colors.white70),
],
const Divider(color: Colors.white24),
_buildSummaryRow("合計金額", "${fmt.format(_total)}", Colors.white, fontSize: 24),
_buildSummaryRow(_includeTax ? "合計金額 (税込)" : "合計金額", "${fmt.format(_total)}", Colors.white, fontSize: 24),
],
),
);
@ -479,8 +536,8 @@ class _InvoiceInputFormState extends State<InvoiceInputForm> {
Expanded(
child: OutlinedButton.icon(
onPressed: _showPreview,
icon: const Icon(Icons.remove_red_eye),
label: const Text("仮表示"),
icon: const Icon(Icons.picture_as_pdf), //
label: const Text("PDFプレビュー"), //
style: OutlinedButton.styleFrom(
padding: const EdgeInsets.symmetric(vertical: 16),
side: const BorderSide(color: Colors.indigo),
@ -521,7 +578,31 @@ class _InvoiceInputFormState extends State<InvoiceInputForm> {
}
Widget _buildDraftToggle() {
// ... (existing code omitted for brevity but I'll provide the new method below it)
return Container(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
decoration: BoxDecoration(
color: _isDraft ? Colors.black26 : Colors.orange.shade50,
borderRadius: BorderRadius.circular(12),
border: Border.all(color: _isDraft ? Colors.orangeAccent : Colors.orange, width: 2),
),
child: Row(
children: [
Icon(_isDraft ? Icons.drafts : Icons.check_circle, color: Colors.orange),
const SizedBox(width: 12),
Expanded(
child: Text(
_isDraft ? "下書き (保存のみ・PDF未生成)" : "正式発行 (PDF生成)",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 13, color: _isDraft ? Colors.white70 : Colors.orange.shade900),
),
),
Switch(
value: _isDraft,
activeColor: Colors.orangeAccent,
onChanged: (val) => setState(() => _isDraft = val),
),
],
),
);
}
Widget _buildSubjectSection(Color textColor) {

View file

@ -2,7 +2,7 @@ import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
class DatabaseHelper {
static const _databaseVersion = 12;
static const _databaseVersion = 13;
static final DatabaseHelper _instance = DatabaseHelper._internal();
static Database? _database;
@ -94,6 +94,9 @@ class DatabaseHelper {
if (oldVersion < 12) {
await db.execute('ALTER TABLE invoices ADD COLUMN subject TEXT');
}
if (oldVersion < 13) {
await db.execute('ALTER TABLE company_info ADD COLUMN registration_number TEXT');
}
}
Future<void> _onCreate(Database db, int version) async {
@ -193,7 +196,8 @@ class DatabaseHelper {
tel TEXT,
default_tax_rate REAL DEFAULT 0.10,
seal_path TEXT,
tax_display_mode TEXT DEFAULT "normal"
tax_display_mode TEXT DEFAULT "normal",
registration_number TEXT
)
''');

View file

@ -96,6 +96,8 @@ Future<pw.Document> buildInvoiceDocument(Invoice invoice) async {
if (companyInfo.zipCode != null) pw.Text("${companyInfo.zipCode}"),
if (companyInfo.address != null) pw.Text(companyInfo.address!),
if (companyInfo.tel != null) pw.Text("TEL: ${companyInfo.tel}"),
if (companyInfo.registrationNumber != null && companyInfo.registrationNumber!.isNotEmpty)
pw.Text("登録番号: ${companyInfo.registrationNumber!}", style: const pw.TextStyle(fontSize: 10)),
],
),
if (sealImage != null)
@ -256,7 +258,20 @@ Future<String?> generateInvoicePdf(Invoice invoice) async {
final String subjectStr = invoice.subject?.isNotEmpty == true ? "_${invoice.subject}" : "";
// {}({}){}_{}_{}_{HASH下8桁}.pdf
String fileName = "${dateStr}(${invoice.documentTypeName})${invoice.customerNameForDisplay}${subjectStr}_${amountStr}円_$hash.pdf";
//
String safeCustomerName = invoice.customerNameForDisplay
.replaceAll('株式会社', '')
.replaceAll('(株)', '')
.replaceAll('(株)', '')
.replaceAll('有限会社', '')
.replaceAll('(有)', '')
.replaceAll('(有)', '')
.replaceAll('合同会社', '')
.replaceAll('(同)', '')
.replaceAll('(同)', '')
.trim();
String fileName = "${dateStr}(${invoice.documentTypeName})${safeCustomerName}${subjectStr}_${amountStr}円_$hash.pdf";
final directory = await getExternalStorageDirectory();
if (directory == null) return null;

View file

@ -56,4 +56,23 @@
20260214(請求書)佐々木製作所_10,000円_12345678.pdf
明細欄にはmarkdown的要素が使える様に、簡単なものが欲しい。
 インデントや箇条書き、太字など。問題はodooとの連携と型番。
+ 編集画面にタイトルが2行出るようになった
+ 配色でバックと文字が同系色になり見えなくなる事がある
+ 「仮表示」は「PDFプレビュー」に名称変更
+ PDFに自社情報が反映されない T番号が有る場合はT番号をPDFに記載する
+ 一覧表示する時はキーボードに隠れる部分があるのでその分余白を表示する
+ 一覧表示・検索の時にも左上には戻る矢印が必須
+ 値引きも商品とするか悩んでいます
+ 税別の場合は編集画面に消費税項目編集部分は表示しない
+ 合計金額部分も税別の時は表示を専用に切り替える
+ 仮表示PDFプレビューに改名は何度でも実行可能にする
+ 伝票入力画面で行の編集が可能にする
+ 顧客マスター呼び出しボタンが請求先マスターになっているのを修正
+ アンロックのスライドの右端が画面外にはみ出している
+ 編集したのを保存すると沢山伝票が増え続ける
+ 商品マスターにはグルーピング機能を追加する(商品を選択すると芋蔓式にインデントした商品が引用される)
+ 顧客マスターにはメールアドレスが必要PDFを送信するから
+ ファイル名には株式会社や有限会社は除去して社名だけを引用する
+ 伝票を新規発行する時は顧客名から引用できる伝票を表示し選択して引用する機能を実装する