diff --git a/hesabixUI/hesabix_ui/lib/models/invoice_transaction.dart b/hesabixUI/hesabix_ui/lib/models/invoice_transaction.dart new file mode 100644 index 0000000..b3b46c1 --- /dev/null +++ b/hesabixUI/hesabix_ui/lib/models/invoice_transaction.dart @@ -0,0 +1,155 @@ +enum TransactionType { + bank('bank', 'بانک'), + cashRegister('cash_register', 'صندوق'), + pettyCash('petty_cash', 'تنخواهگردان'), + check('check', 'چک'), + checkExpense('check_expense', 'خرج چک'), + person('person', 'شخص'), + account('account', 'حساب'); + + const TransactionType(this.value, this.label); + + final String value; + final String label; + + static TransactionType? fromValue(String value) { + for (final type in TransactionType.values) { + if (type.value == value) { + return type; + } + } + return null; + } + + static List get allTypes => TransactionType.values; +} + +class InvoiceTransaction { + final String id; + final TransactionType type; + final String? bankId; + final String? bankName; + final String? cashRegisterId; + final String? cashRegisterName; + final String? pettyCashId; + final String? pettyCashName; + final String? checkId; + final String? checkNumber; + final String? personId; + final String? personName; + final String? accountId; + final String? accountName; + final DateTime transactionDate; + final num amount; + final num? commission; + final String? description; + + const InvoiceTransaction({ + required this.id, + required this.type, + this.bankId, + this.bankName, + this.cashRegisterId, + this.cashRegisterName, + this.pettyCashId, + this.pettyCashName, + this.checkId, + this.checkNumber, + this.personId, + this.personName, + this.accountId, + this.accountName, + required this.transactionDate, + required this.amount, + this.commission, + this.description, + }); + + InvoiceTransaction copyWith({ + String? id, + TransactionType? type, + String? bankId, + String? bankName, + String? cashRegisterId, + String? cashRegisterName, + String? pettyCashId, + String? pettyCashName, + String? checkId, + String? checkNumber, + String? personId, + String? personName, + String? accountId, + String? accountName, + DateTime? transactionDate, + num? amount, + num? commission, + String? description, + }) { + return InvoiceTransaction( + id: id ?? this.id, + type: type ?? this.type, + bankId: bankId ?? this.bankId, + bankName: bankName ?? this.bankName, + cashRegisterId: cashRegisterId ?? this.cashRegisterId, + cashRegisterName: cashRegisterName ?? this.cashRegisterName, + pettyCashId: pettyCashId ?? this.pettyCashId, + pettyCashName: pettyCashName ?? this.pettyCashName, + checkId: checkId ?? this.checkId, + checkNumber: checkNumber ?? this.checkNumber, + personId: personId ?? this.personId, + personName: personName ?? this.personName, + accountId: accountId ?? this.accountId, + accountName: accountName ?? this.accountName, + transactionDate: transactionDate ?? this.transactionDate, + amount: amount ?? this.amount, + commission: commission ?? this.commission, + description: description ?? this.description, + ); + } + + Map toJson() { + return { + 'id': id, + 'type': type.value, + 'bank_id': bankId, + 'bank_name': bankName, + 'cash_register_id': cashRegisterId, + 'cash_register_name': cashRegisterName, + 'petty_cash_id': pettyCashId, + 'petty_cash_name': pettyCashName, + 'check_id': checkId, + 'check_number': checkNumber, + 'person_id': personId, + 'person_name': personName, + 'account_id': accountId, + 'account_name': accountName, + 'transaction_date': transactionDate.toIso8601String(), + 'amount': amount, + 'commission': commission, + 'description': description, + }; + } + + factory InvoiceTransaction.fromJson(Map json) { + return InvoiceTransaction( + id: json['id'] as String, + type: TransactionType.fromValue(json['type'] as String) ?? TransactionType.person, + bankId: json['bank_id'] as String?, + bankName: json['bank_name'] as String?, + cashRegisterId: json['cash_register_id'] as String?, + cashRegisterName: json['cash_register_name'] as String?, + pettyCashId: json['petty_cash_id'] as String?, + pettyCashName: json['petty_cash_name'] as String?, + checkId: json['check_id'] as String?, + checkNumber: json['check_number'] as String?, + personId: json['person_id'] as String?, + personName: json['person_name'] as String?, + accountId: json['account_id'] as String?, + accountName: json['account_name'] as String?, + transactionDate: DateTime.parse(json['transaction_date'] as String), + amount: json['amount'] as num, + commission: json['commission'] as num?, + description: json['description'] as String?, + ); + } +} diff --git a/hesabixUI/hesabix_ui/lib/pages/business/new_invoice_page.dart b/hesabixUI/hesabix_ui/lib/pages/business/new_invoice_page.dart index 1cf4b28..8f7a9a0 100644 --- a/hesabixUI/hesabix_ui/lib/pages/business/new_invoice_page.dart +++ b/hesabixUI/hesabix_ui/lib/pages/business/new_invoice_page.dart @@ -16,9 +16,11 @@ import '../../models/invoice_type_model.dart'; import '../../models/customer_model.dart'; import '../../models/person_model.dart'; import '../../widgets/invoice/line_items_table.dart'; +import '../../widgets/invoice/invoice_transactions_widget.dart'; import '../../utils/number_formatters.dart'; import '../../services/currency_service.dart'; import '../../core/api_client.dart'; +import '../../models/invoice_transaction.dart'; class NewInvoicePage extends StatefulWidget { final int businessId; @@ -66,6 +68,9 @@ class _NewInvoicePageState extends State with SingleTickerProvid bool _isOfficialInvoice = false; String? _selectedPrintTemplate; bool _sendToTaxFolder = false; + + // تراکنش‌های فاکتور + List _transactions = []; @override void initState() { @@ -708,10 +713,11 @@ class _NewInvoicePageState extends State with SingleTickerProvid // TODO: پیاده‌سازی عملیات ذخیره فاکتور final printInfo = _printAfterSave ? '\n• چاپ فاکتور: فعال' : ''; final taxInfo = _sendToTaxFolder ? '\n• ارسال به کارپوشه مودیان: فعال' : ''; + final transactionInfo = _transactions.isNotEmpty ? '\n• تعداد تراکنش‌ها: ${_transactions.length}' : ''; ScaffoldMessenger.of(context).showSnackBar( SnackBar( - content: Text('عملیات ذخیره فاکتور به زودی پیاده‌سازی خواهد شد$printInfo$taxInfo'), + content: Text('عملیات ذخیره فاکتور به زودی پیاده‌سازی خواهد شد$printInfo$taxInfo$transactionInfo'), backgroundColor: Theme.of(context).colorScheme.primary, duration: const Duration(seconds: 3), ), @@ -763,33 +769,22 @@ class _NewInvoicePageState extends State with SingleTickerProvid } Widget _buildTransactionsTab() { - return const Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon( - Icons.receipt_long_outlined, - size: 64, - color: Colors.grey, + return Padding( + padding: const EdgeInsets.all(16), + child: Center( + child: ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 1200), + child: InvoiceTransactionsWidget( + transactions: _transactions, + businessId: widget.businessId, + calendarController: widget.calendarController, + onChanged: (transactions) { + setState(() { + _transactions = transactions; + }); + }, ), - SizedBox(height: 16), - Text( - 'تراکنش‌ها', - style: TextStyle( - fontSize: 24, - fontWeight: FontWeight.bold, - color: Colors.grey, - ), - ), - SizedBox(height: 8), - Text( - 'این بخش در آینده پیاده‌سازی خواهد شد', - style: TextStyle( - fontSize: 16, - color: Colors.grey, - ), - ), - ], + ), ), ); } diff --git a/hesabixUI/hesabix_ui/lib/widgets/invoice/invoice_transactions_widget.dart b/hesabixUI/hesabix_ui/lib/widgets/invoice/invoice_transactions_widget.dart new file mode 100644 index 0000000..d779242 --- /dev/null +++ b/hesabixUI/hesabix_ui/lib/widgets/invoice/invoice_transactions_widget.dart @@ -0,0 +1,830 @@ +import 'package:flutter/material.dart'; +import 'package:uuid/uuid.dart'; +import '../../models/invoice_transaction.dart'; +import '../../core/date_utils.dart'; +import '../../core/calendar_controller.dart'; +import '../../utils/number_formatters.dart'; + +class InvoiceTransactionsWidget extends StatefulWidget { + final List transactions; + final ValueChanged> onChanged; + final int businessId; + final CalendarController calendarController; + + const InvoiceTransactionsWidget({ + super.key, + required this.transactions, + required this.onChanged, + required this.businessId, + required this.calendarController, + }); + + @override + State createState() => _InvoiceTransactionsWidgetState(); +} + +class _InvoiceTransactionsWidgetState extends State { + + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + + return Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + // هدر + Row( + children: [ + Icon( + Icons.receipt_long_outlined, + color: theme.colorScheme.primary, + size: 24, + ), + const SizedBox(width: 8), + Text( + 'تراکنش‌های فاکتور', + style: theme.textTheme.titleLarge?.copyWith( + fontWeight: FontWeight.bold, + ), + ), + const Spacer(), + ElevatedButton.icon( + onPressed: _addTransaction, + icon: const Icon(Icons.add), + label: const Text('افزودن تراکنش'), + style: ElevatedButton.styleFrom( + backgroundColor: theme.colorScheme.primary, + foregroundColor: theme.colorScheme.onPrimary, + ), + ), + ], + ), + const SizedBox(height: 16), + + // لیست تراکنش‌ها + if (widget.transactions.isEmpty) + Card( + child: Padding( + padding: const EdgeInsets.all(32), + child: Column( + children: [ + Icon( + Icons.receipt_long_outlined, + size: 48, + color: theme.colorScheme.outline, + ), + const SizedBox(height: 16), + Text( + 'هیچ تراکنشی اضافه نشده است', + style: theme.textTheme.titleMedium?.copyWith( + color: theme.colorScheme.outline, + ), + ), + const SizedBox(height: 8), + Text( + 'برای افزودن تراکنش روی دکمه "افزودن تراکنش" کلیک کنید', + style: theme.textTheme.bodyMedium?.copyWith( + color: theme.colorScheme.outline, + ), + ), + ], + ), + ), + ) + else + ListView.separated( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemCount: widget.transactions.length, + separatorBuilder: (context, index) => const SizedBox(height: 12), + itemBuilder: (context, index) { + final transaction = widget.transactions[index]; + return _buildTransactionCard(transaction, index); + }, + ), + ], + ); + } + + Widget _buildTransactionCard(InvoiceTransaction transaction, int index) { + final theme = Theme.of(context); + + return Card( + child: Padding( + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // هدر تراکنش + Row( + children: [ + Icon( + _getTransactionIcon(transaction.type), + color: theme.colorScheme.primary, + size: 20, + ), + const SizedBox(width: 8), + Text( + transaction.type.label, + style: theme.textTheme.titleMedium?.copyWith( + fontWeight: FontWeight.w600, + ), + ), + const Spacer(), + Text( + formatWithThousands(transaction.amount, decimalPlaces: 0), + style: theme.textTheme.titleMedium?.copyWith( + fontWeight: FontWeight.bold, + color: theme.colorScheme.primary, + ), + ), + const SizedBox(width: 8), + IconButton( + onPressed: () => _editTransaction(index), + icon: const Icon(Icons.edit), + tooltip: 'ویرایش', + ), + IconButton( + onPressed: () => _removeTransaction(index), + icon: const Icon(Icons.delete), + tooltip: 'حذف', + color: theme.colorScheme.error, + ), + ], + ), + const SizedBox(height: 12), + + // جزئیات تراکنش + _buildTransactionDetails(transaction), + ], + ), + ), + ); + } + + Widget _buildTransactionDetails(InvoiceTransaction transaction) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // نام/عنوان تراکنش + if (transaction.bankName != null) + _buildDetailRow('بانک:', transaction.bankName!), + if (transaction.cashRegisterName != null) + _buildDetailRow('صندوق:', transaction.cashRegisterName!), + if (transaction.pettyCashName != null) + _buildDetailRow('تنخواهگردان:', transaction.pettyCashName!), + if (transaction.checkNumber != null) + _buildDetailRow('شماره چک:', transaction.checkNumber!), + if (transaction.personName != null) + _buildDetailRow('شخص:', transaction.personName!), + if (transaction.accountName != null) + _buildDetailRow('حساب:', transaction.accountName!), + + const SizedBox(height: 8), + + // تاریخ و مبلغ + Row( + children: [ + Expanded( + child: _buildDetailRow( + 'تاریخ:', + HesabixDateUtils.formatForDisplay( + transaction.transactionDate, + widget.calendarController.isJalali == true, + ), + ), + ), + if (transaction.commission != null) + Expanded( + child: _buildDetailRow( + 'کارمزد:', + formatWithThousands(transaction.commission!, decimalPlaces: 0), + ), + ), + ], + ), + + // توضیحات + if (transaction.description != null && transaction.description!.isNotEmpty) ...[ + const SizedBox(height: 8), + _buildDetailRow('توضیحات:', transaction.description!), + ], + ], + ); + } + + Widget _buildDetailRow(String label, String value) { + final theme = Theme.of(context); + + return Padding( + padding: const EdgeInsets.only(bottom: 4), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + width: 80, + child: Text( + label, + style: theme.textTheme.bodyMedium?.copyWith( + fontWeight: FontWeight.w500, + color: theme.colorScheme.onSurfaceVariant, + ), + ), + ), + Expanded( + child: Text( + value, + style: theme.textTheme.bodyMedium, + ), + ), + ], + ), + ); + } + + IconData _getTransactionIcon(TransactionType type) { + switch (type) { + case TransactionType.bank: + return Icons.account_balance; + case TransactionType.cashRegister: + return Icons.point_of_sale; + case TransactionType.pettyCash: + return Icons.wallet; + case TransactionType.check: + return Icons.receipt; + case TransactionType.checkExpense: + return Icons.receipt_long; + case TransactionType.person: + return Icons.person; + case TransactionType.account: + return Icons.account_balance_wallet; + } + } + + void _addTransaction() { + _showTransactionDialog(); + } + + void _editTransaction(int index) { + _showTransactionDialog(transaction: widget.transactions[index], index: index); + } + + void _removeTransaction(int index) { + showDialog( + context: context, + builder: (context) => AlertDialog( + title: const Text('حذف تراکنش'), + content: const Text('آیا از حذف این تراکنش اطمینان دارید؟'), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: const Text('انصراف'), + ), + TextButton( + onPressed: () { + Navigator.pop(context); + _removeTransactionAt(index); + }, + child: const Text('حذف'), + ), + ], + ), + ); + } + + void _removeTransactionAt(int index) { + final newTransactions = List.from(widget.transactions); + newTransactions.removeAt(index); + widget.onChanged(newTransactions); + } + + void _showTransactionDialog({InvoiceTransaction? transaction, int? index}) { + showDialog( + context: context, + builder: (context) => TransactionDialog( + transaction: transaction, + businessId: widget.businessId, + calendarController: widget.calendarController, + onSave: (newTransaction) { + if (index != null) { + // ویرایش تراکنش موجود + final newTransactions = List.from(widget.transactions); + newTransactions[index] = newTransaction; + widget.onChanged(newTransactions); + } else { + // افزودن تراکنش جدید + final newTransactions = List.from(widget.transactions); + newTransactions.add(newTransaction); + widget.onChanged(newTransactions); + } + }, + ), + ); + } +} + +class TransactionDialog extends StatefulWidget { + final InvoiceTransaction? transaction; + final int businessId; + final CalendarController calendarController; + final ValueChanged onSave; + + const TransactionDialog({ + super.key, + this.transaction, + required this.businessId, + required this.calendarController, + required this.onSave, + }); + + @override + State createState() => _TransactionDialogState(); +} + +class _TransactionDialogState extends State { + final _formKey = GlobalKey(); + final _uuid = const Uuid(); + + late TransactionType _selectedType; + DateTime _transactionDate = DateTime.now(); + final _amountController = TextEditingController(); + final _commissionController = TextEditingController(); + final _descriptionController = TextEditingController(); + + // فیلدهای خاص هر نوع تراکنش + String? _selectedBankId; + String? _selectedCashRegisterId; + String? _selectedPettyCashId; + String? _selectedCheckId; + String? _selectedPersonId; + String? _selectedAccountId; + + @override + void initState() { + super.initState(); + _selectedType = widget.transaction?.type ?? TransactionType.person; + _transactionDate = widget.transaction?.transactionDate ?? DateTime.now(); + _amountController.text = widget.transaction?.amount.toString() ?? ''; + _commissionController.text = widget.transaction?.commission?.toString() ?? ''; + _descriptionController.text = widget.transaction?.description ?? ''; + + // تنظیم فیلدهای خاص + _selectedBankId = widget.transaction?.bankId; + _selectedCashRegisterId = widget.transaction?.cashRegisterId; + _selectedPettyCashId = widget.transaction?.pettyCashId; + _selectedCheckId = widget.transaction?.checkId; + _selectedPersonId = widget.transaction?.personId; + _selectedAccountId = widget.transaction?.accountId; + } + + @override + void dispose() { + _amountController.dispose(); + _commissionController.dispose(); + _descriptionController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + + return Dialog( + child: Container( + width: 600, + constraints: const BoxConstraints(maxHeight: 600), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + // هدر + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: theme.colorScheme.primary, + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(12), + topRight: Radius.circular(12), + ), + ), + child: Row( + children: [ + Icon( + Icons.receipt_long_outlined, + color: theme.colorScheme.onPrimary, + size: 24, + ), + const SizedBox(width: 8), + Text( + widget.transaction != null ? 'ویرایش تراکنش' : 'افزودن تراکنش', + style: theme.textTheme.titleLarge?.copyWith( + color: theme.colorScheme.onPrimary, + fontWeight: FontWeight.bold, + ), + ), + const Spacer(), + IconButton( + onPressed: () => Navigator.pop(context), + icon: const Icon(Icons.close), + color: theme.colorScheme.onPrimary, + ), + ], + ), + ), + + // فرم + Expanded( + child: SingleChildScrollView( + padding: const EdgeInsets.all(16), + child: Form( + key: _formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + // انتخاب نوع تراکنش + DropdownButtonFormField( + initialValue: _selectedType, + decoration: const InputDecoration( + labelText: 'نوع تراکنش *', + border: OutlineInputBorder(), + ), + items: TransactionType.allTypes.map((type) { + return DropdownMenuItem( + value: type, + child: Text(type.label), + ); + }).toList(), + onChanged: (value) { + if (value != null) { + setState(() { + _selectedType = value; + }); + } + }, + ), + const SizedBox(height: 16), + + // فیلدهای خاص بر اساس نوع تراکنش + _buildTypeSpecificFields(), + const SizedBox(height: 16), + + // تاریخ تراکنش + Row( + children: [ + Expanded( + child: TextFormField( + readOnly: true, + decoration: InputDecoration( + labelText: 'تاریخ تراکنش *', + border: const OutlineInputBorder(), + suffixIcon: const Icon(Icons.calendar_today), + ), + onTap: () => _selectDate(), + controller: TextEditingController( + text: HesabixDateUtils.formatForDisplay( + _transactionDate, + widget.calendarController.isJalali == true, + ), + ), + ), + ), + ], + ), + const SizedBox(height: 16), + + // مبلغ و کارمزد + Row( + children: [ + Expanded( + child: TextFormField( + controller: _amountController, + decoration: const InputDecoration( + labelText: 'مبلغ *', + border: OutlineInputBorder(), + suffixText: 'ریال', + ), + keyboardType: TextInputType.number, + validator: (value) { + if (value == null || value.isEmpty) { + return 'مبلغ الزامی است'; + } + if (double.tryParse(value) == null) { + return 'مبلغ باید عدد باشد'; + } + return null; + }, + ), + ), + const SizedBox(width: 16), + Expanded( + child: TextFormField( + controller: _commissionController, + decoration: const InputDecoration( + labelText: 'کارمزد', + border: OutlineInputBorder(), + suffixText: 'ریال', + ), + keyboardType: TextInputType.number, + ), + ), + ], + ), + const SizedBox(height: 16), + + // توضیحات + TextFormField( + controller: _descriptionController, + decoration: const InputDecoration( + labelText: 'توضیحات', + border: OutlineInputBorder(), + ), + maxLines: 3, + ), + ], + ), + ), + ), + ), + + // دکمه‌ها + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: theme.colorScheme.surfaceContainerHighest, + borderRadius: const BorderRadius.only( + bottomLeft: Radius.circular(12), + bottomRight: Radius.circular(12), + ), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: const Text('انصراف'), + ), + const SizedBox(width: 8), + ElevatedButton( + onPressed: _saveTransaction, + child: Text(widget.transaction != null ? 'ذخیره' : 'افزودن'), + ), + ], + ), + ), + ], + ), + ), + ); + } + + Widget _buildTypeSpecificFields() { + switch (_selectedType) { + case TransactionType.bank: + return _buildBankFields(); + case TransactionType.cashRegister: + return _buildCashRegisterFields(); + case TransactionType.pettyCash: + return _buildPettyCashFields(); + case TransactionType.check: + return _buildCheckFields(); + case TransactionType.checkExpense: + return _buildCheckExpenseFields(); + case TransactionType.person: + return _buildPersonFields(); + case TransactionType.account: + return _buildAccountFields(); + } + } + + Widget _buildBankFields() { + return DropdownButtonFormField( + initialValue: _selectedBankId, + decoration: const InputDecoration( + labelText: 'بانک *', + border: OutlineInputBorder(), + ), + items: const [ + DropdownMenuItem(value: 'bank1', child: Text('بانک ملی')), + DropdownMenuItem(value: 'bank2', child: Text('بانک صادرات')), + DropdownMenuItem(value: 'bank3', child: Text('بانک ملت')), + ], + onChanged: (value) { + setState(() { + _selectedBankId = value; + }); + }, + ); + } + + Widget _buildCashRegisterFields() { + return DropdownButtonFormField( + initialValue: _selectedCashRegisterId, + decoration: const InputDecoration( + labelText: 'صندوق *', + border: OutlineInputBorder(), + ), + items: const [ + DropdownMenuItem(value: 'cash1', child: Text('صندوق اصلی')), + DropdownMenuItem(value: 'cash2', child: Text('صندوق فرعی')), + ], + onChanged: (value) { + setState(() { + _selectedCashRegisterId = value; + }); + }, + ); + } + + Widget _buildPettyCashFields() { + return DropdownButtonFormField( + initialValue: _selectedPettyCashId, + decoration: const InputDecoration( + labelText: 'تنخواهگردان *', + border: OutlineInputBorder(), + ), + items: const [ + DropdownMenuItem(value: 'petty1', child: Text('تنخواهگردان اصلی')), + DropdownMenuItem(value: 'petty2', child: Text('تنخواهگردان فرعی')), + ], + onChanged: (value) { + setState(() { + _selectedPettyCashId = value; + }); + }, + ); + } + + Widget _buildCheckFields() { + return DropdownButtonFormField( + initialValue: _selectedCheckId, + decoration: const InputDecoration( + labelText: 'چک *', + border: OutlineInputBorder(), + ), + items: const [ + DropdownMenuItem(value: 'check1', child: Text('چک شماره 123456')), + DropdownMenuItem(value: 'check2', child: Text('چک شماره 789012')), + ], + onChanged: (value) { + setState(() { + _selectedCheckId = value; + }); + }, + ); + } + + Widget _buildCheckExpenseFields() { + return DropdownButtonFormField( + initialValue: _selectedCheckId, + decoration: const InputDecoration( + labelText: 'خرج چک *', + border: OutlineInputBorder(), + ), + items: const [ + DropdownMenuItem(value: 'expense1', child: Text('خرج چک شماره 123456')), + DropdownMenuItem(value: 'expense2', child: Text('خرج چک شماره 789012')), + ], + onChanged: (value) { + setState(() { + _selectedCheckId = value; + }); + }, + ); + } + + Widget _buildPersonFields() { + return DropdownButtonFormField( + initialValue: _selectedPersonId, + decoration: const InputDecoration( + labelText: 'شخص *', + border: OutlineInputBorder(), + ), + items: const [ + DropdownMenuItem(value: 'person1', child: Text('احمد محمدی')), + DropdownMenuItem(value: 'person2', child: Text('فاطمه احمدی')), + ], + onChanged: (value) { + setState(() { + _selectedPersonId = value; + }); + }, + ); + } + + Widget _buildAccountFields() { + return DropdownButtonFormField( + initialValue: _selectedAccountId, + decoration: const InputDecoration( + labelText: 'حساب *', + border: OutlineInputBorder(), + ), + items: const [ + DropdownMenuItem(value: 'account1', child: Text('حساب جاری')), + DropdownMenuItem(value: 'account2', child: Text('حساب پس‌انداز')), + ], + onChanged: (value) { + setState(() { + _selectedAccountId = value; + }); + }, + ); + } + + Future _selectDate() async { + final date = await showDatePicker( + context: context, + initialDate: _transactionDate, + firstDate: DateTime(2020), + lastDate: DateTime(2030), + ); + + if (date != null) { + setState(() { + _transactionDate = date; + }); + } + } + + void _saveTransaction() { + if (!_formKey.currentState!.validate()) return; + + final amount = double.parse(_amountController.text); + final commission = _commissionController.text.isNotEmpty + ? double.parse(_commissionController.text) + : null; + + final transaction = InvoiceTransaction( + id: widget.transaction?.id ?? _uuid.v4(), + type: _selectedType, + bankId: _selectedBankId, + bankName: _getBankName(_selectedBankId), + cashRegisterId: _selectedCashRegisterId, + cashRegisterName: _getCashRegisterName(_selectedCashRegisterId), + pettyCashId: _selectedPettyCashId, + pettyCashName: _getPettyCashName(_selectedPettyCashId), + checkId: _selectedCheckId, + checkNumber: _getCheckNumber(_selectedCheckId), + personId: _selectedPersonId, + personName: _getPersonName(_selectedPersonId), + accountId: _selectedAccountId, + accountName: _getAccountName(_selectedAccountId), + transactionDate: _transactionDate, + amount: amount, + commission: commission, + description: _descriptionController.text.trim().isEmpty + ? null + : _descriptionController.text.trim(), + ); + + widget.onSave(transaction); + Navigator.pop(context); + } + + String? _getBankName(String? id) { + switch (id) { + case 'bank1': return 'بانک ملی'; + case 'bank2': return 'بانک صادرات'; + case 'bank3': return 'بانک ملت'; + default: return null; + } + } + + String? _getCashRegisterName(String? id) { + switch (id) { + case 'cash1': return 'صندوق اصلی'; + case 'cash2': return 'صندوق فرعی'; + default: return null; + } + } + + String? _getPettyCashName(String? id) { + switch (id) { + case 'petty1': return 'تنخواهگردان اصلی'; + case 'petty2': return 'تنخواهگردان فرعی'; + default: return null; + } + } + + String? _getCheckNumber(String? id) { + switch (id) { + case 'check1': return '123456'; + case 'check2': return '789012'; + default: return null; + } + } + + String? _getPersonName(String? id) { + switch (id) { + case 'person1': return 'احمد محمدی'; + case 'person2': return 'فاطمه احمدی'; + default: return null; + } + } + + String? _getAccountName(String? id) { + switch (id) { + case 'account1': return 'حساب جاری'; + case 'account2': return 'حساب پس‌انداز'; + default: return null; + } + } +}