Matching transactions

This commit is contained in:
Hillel Coren 2022-12-01 11:10:38 +02:00
parent 8083c8ef6d
commit d0e48817ba
5 changed files with 161 additions and 91 deletions

View File

@ -92,6 +92,7 @@ abstract class TransactionEntity extends Object
transactionId: 0, transactionId: 0,
categoryId: '', categoryId: '',
transactionRuleId: '', transactionRuleId: '',
paymentId: '',
); );
} }
@ -131,6 +132,9 @@ abstract class TransactionEntity extends Object
@BuiltValueField(wireName: 'invoice_ids') @BuiltValueField(wireName: 'invoice_ids')
String get invoiceIds; String get invoiceIds;
@BuiltValueField(wireName: 'payment_id')
String get paymentId;
@BuiltValueField(wireName: 'expense_id') @BuiltValueField(wireName: 'expense_id')
String get expenseId; String get expenseId;
@ -359,6 +363,7 @@ abstract class TransactionEntity extends Object
..baseType = '' ..baseType = ''
..bankAccountId = '' ..bankAccountId = ''
..transactionRuleId = '' ..transactionRuleId = ''
..paymentId = ''
..currencyId = ''; ..currencyId = '';
static Serializer<TransactionEntity> get serializer => static Serializer<TransactionEntity> get serializer =>

View File

@ -151,6 +151,9 @@ class _$TransactionEntitySerializer
'invoice_ids', 'invoice_ids',
serializers.serialize(object.invoiceIds, serializers.serialize(object.invoiceIds,
specifiedType: const FullType(String)), specifiedType: const FullType(String)),
'payment_id',
serializers.serialize(object.paymentId,
specifiedType: const FullType(String)),
'expense_id', 'expense_id',
serializers.serialize(object.expenseId, serializers.serialize(object.expenseId,
specifiedType: const FullType(String)), specifiedType: const FullType(String)),
@ -259,6 +262,10 @@ class _$TransactionEntitySerializer
result.invoiceIds = serializers.deserialize(value, result.invoiceIds = serializers.deserialize(value,
specifiedType: const FullType(String)) as String; specifiedType: const FullType(String)) as String;
break; break;
case 'payment_id':
result.paymentId = serializers.deserialize(value,
specifiedType: const FullType(String)) as String;
break;
case 'expense_id': case 'expense_id':
result.expenseId = serializers.deserialize(value, result.expenseId = serializers.deserialize(value,
specifiedType: const FullType(String)) as String; specifiedType: const FullType(String)) as String;
@ -577,6 +584,8 @@ class _$TransactionEntity extends TransactionEntity {
@override @override
final String invoiceIds; final String invoiceIds;
@override @override
final String paymentId;
@override
final String expenseId; final String expenseId;
@override @override
final String vendorId; final String vendorId;
@ -620,6 +629,7 @@ class _$TransactionEntity extends TransactionEntity {
this.statusId, this.statusId,
this.categoryId, this.categoryId,
this.invoiceIds, this.invoiceIds,
this.paymentId,
this.expenseId, this.expenseId,
this.vendorId, this.vendorId,
this.transactionId, this.transactionId,
@ -654,6 +664,8 @@ class _$TransactionEntity extends TransactionEntity {
categoryId, 'TransactionEntity', 'categoryId'); categoryId, 'TransactionEntity', 'categoryId');
BuiltValueNullFieldError.checkNotNull( BuiltValueNullFieldError.checkNotNull(
invoiceIds, 'TransactionEntity', 'invoiceIds'); invoiceIds, 'TransactionEntity', 'invoiceIds');
BuiltValueNullFieldError.checkNotNull(
paymentId, 'TransactionEntity', 'paymentId');
BuiltValueNullFieldError.checkNotNull( BuiltValueNullFieldError.checkNotNull(
expenseId, 'TransactionEntity', 'expenseId'); expenseId, 'TransactionEntity', 'expenseId');
BuiltValueNullFieldError.checkNotNull( BuiltValueNullFieldError.checkNotNull(
@ -693,6 +705,7 @@ class _$TransactionEntity extends TransactionEntity {
statusId == other.statusId && statusId == other.statusId &&
categoryId == other.categoryId && categoryId == other.categoryId &&
invoiceIds == other.invoiceIds && invoiceIds == other.invoiceIds &&
paymentId == other.paymentId &&
expenseId == other.expenseId && expenseId == other.expenseId &&
vendorId == other.vendorId && vendorId == other.vendorId &&
transactionId == other.transactionId && transactionId == other.transactionId &&
@ -730,12 +743,12 @@ class _$TransactionEntity extends TransactionEntity {
$jc( $jc(
$jc( $jc(
$jc( $jc(
$jc($jc($jc($jc($jc($jc(0, amount.hashCode), currencyId.hashCode), category.hashCode), baseType.hashCode), date.hashCode), $jc($jc($jc($jc($jc($jc($jc(0, amount.hashCode), currencyId.hashCode), category.hashCode), baseType.hashCode), date.hashCode), bankAccountId.hashCode),
bankAccountId.hashCode),
description.hashCode), description.hashCode),
statusId.hashCode), statusId.hashCode),
categoryId.hashCode), categoryId.hashCode),
invoiceIds.hashCode), invoiceIds.hashCode),
paymentId.hashCode),
expenseId.hashCode), expenseId.hashCode),
vendorId.hashCode), vendorId.hashCode),
transactionId.hashCode), transactionId.hashCode),
@ -765,6 +778,7 @@ class _$TransactionEntity extends TransactionEntity {
..add('statusId', statusId) ..add('statusId', statusId)
..add('categoryId', categoryId) ..add('categoryId', categoryId)
..add('invoiceIds', invoiceIds) ..add('invoiceIds', invoiceIds)
..add('paymentId', paymentId)
..add('expenseId', expenseId) ..add('expenseId', expenseId)
..add('vendorId', vendorId) ..add('vendorId', vendorId)
..add('transactionId', transactionId) ..add('transactionId', transactionId)
@ -828,6 +842,10 @@ class TransactionEntityBuilder
String get invoiceIds => _$this._invoiceIds; String get invoiceIds => _$this._invoiceIds;
set invoiceIds(String invoiceIds) => _$this._invoiceIds = invoiceIds; set invoiceIds(String invoiceIds) => _$this._invoiceIds = invoiceIds;
String _paymentId;
String get paymentId => _$this._paymentId;
set paymentId(String paymentId) => _$this._paymentId = paymentId;
String _expenseId; String _expenseId;
String get expenseId => _$this._expenseId; String get expenseId => _$this._expenseId;
set expenseId(String expenseId) => _$this._expenseId = expenseId; set expenseId(String expenseId) => _$this._expenseId = expenseId;
@ -906,6 +924,7 @@ class TransactionEntityBuilder
_statusId = $v.statusId; _statusId = $v.statusId;
_categoryId = $v.categoryId; _categoryId = $v.categoryId;
_invoiceIds = $v.invoiceIds; _invoiceIds = $v.invoiceIds;
_paymentId = $v.paymentId;
_expenseId = $v.expenseId; _expenseId = $v.expenseId;
_vendorId = $v.vendorId; _vendorId = $v.vendorId;
_transactionId = $v.transactionId; _transactionId = $v.transactionId;
@ -956,9 +975,10 @@ class TransactionEntityBuilder
description, 'TransactionEntity', 'description'), description, 'TransactionEntity', 'description'),
statusId: BuiltValueNullFieldError.checkNotNull( statusId: BuiltValueNullFieldError.checkNotNull(
statusId, 'TransactionEntity', 'statusId'), statusId, 'TransactionEntity', 'statusId'),
categoryId: BuiltValueNullFieldError.checkNotNull( categoryId:
categoryId, 'TransactionEntity', 'categoryId'), BuiltValueNullFieldError.checkNotNull(categoryId, 'TransactionEntity', 'categoryId'),
invoiceIds: BuiltValueNullFieldError.checkNotNull(invoiceIds, 'TransactionEntity', 'invoiceIds'), invoiceIds: BuiltValueNullFieldError.checkNotNull(invoiceIds, 'TransactionEntity', 'invoiceIds'),
paymentId: BuiltValueNullFieldError.checkNotNull(paymentId, 'TransactionEntity', 'paymentId'),
expenseId: BuiltValueNullFieldError.checkNotNull(expenseId, 'TransactionEntity', 'expenseId'), expenseId: BuiltValueNullFieldError.checkNotNull(expenseId, 'TransactionEntity', 'expenseId'),
vendorId: BuiltValueNullFieldError.checkNotNull(vendorId, 'TransactionEntity', 'vendorId'), vendorId: BuiltValueNullFieldError.checkNotNull(vendorId, 'TransactionEntity', 'vendorId'),
transactionId: BuiltValueNullFieldError.checkNotNull(transactionId, 'TransactionEntity', 'transactionId'), transactionId: BuiltValueNullFieldError.checkNotNull(transactionId, 'TransactionEntity', 'transactionId'),

View File

@ -11,9 +11,9 @@ import 'package:invoiceninja_flutter/utils/platforms.dart';
class BoolDropdownButton extends StatelessWidget { class BoolDropdownButton extends StatelessWidget {
const BoolDropdownButton({ const BoolDropdownButton({
@required this.label,
@required this.value, @required this.value,
@required this.onChanged, @required this.onChanged,
this.label,
this.showBlank, this.showBlank,
this.enabledLabel, this.enabledLabel,
this.helpLabel, this.helpLabel,
@ -57,13 +57,7 @@ class BoolDropdownButton extends StatelessWidget {
); );
} }
return InputDecorator( final widget = _showBlank
decoration: InputDecoration(
border: _showBlank ? null : InputBorder.none,
labelText: label,
),
isEmpty: '${value ?? ''}'.isEmpty,
child: _showBlank
? DropdownButtonHideUnderline( ? DropdownButtonHideUnderline(
child: DropdownButton<bool>( child: DropdownButton<bool>(
value: value, value: value,
@ -89,8 +83,7 @@ class BoolDropdownButton extends StatelessWidget {
: Padding( : Padding(
padding: const EdgeInsets.only(top: 4), padding: const EdgeInsets.only(top: 4),
child: Flex( child: Flex(
direction: direction: isDesktop(context) ? Axis.horizontal : Axis.vertical,
isDesktop(context) ? Axis.horizontal : Axis.vertical,
children: <Widget>[ children: <Widget>[
InkWell( InkWell(
onTap: () => onChanged(false), onTap: () => onChanged(false),
@ -138,6 +131,18 @@ class BoolDropdownButton extends StatelessWidget {
), ),
], ],
), ),
)); );
if (label == null) {
return widget;
}
return InputDecorator(
decoration: InputDecoration(
border: _showBlank ? null : InputBorder.none,
labelText: label,
),
isEmpty: '${value ?? ''}'.isEmpty,
child: widget);
} }
} }

View File

@ -11,6 +11,7 @@ import 'package:invoiceninja_flutter/redux/ui/ui_actions.dart';
import 'package:invoiceninja_flutter/ui/app/buttons/elevated_button.dart'; import 'package:invoiceninja_flutter/ui/app/buttons/elevated_button.dart';
import 'package:invoiceninja_flutter/ui/app/entities/entity_list_tile.dart'; import 'package:invoiceninja_flutter/ui/app/entities/entity_list_tile.dart';
import 'package:invoiceninja_flutter/ui/app/entity_header.dart'; import 'package:invoiceninja_flutter/ui/app/entity_header.dart';
import 'package:invoiceninja_flutter/ui/app/forms/bool_dropdown_button.dart';
import 'package:invoiceninja_flutter/ui/app/forms/date_picker.dart'; import 'package:invoiceninja_flutter/ui/app/forms/date_picker.dart';
import 'package:invoiceninja_flutter/ui/app/forms/decorated_form_field.dart'; import 'package:invoiceninja_flutter/ui/app/forms/decorated_form_field.dart';
import 'package:invoiceninja_flutter/ui/app/lists/list_divider.dart'; import 'package:invoiceninja_flutter/ui/app/lists/list_divider.dart';
@ -151,6 +152,7 @@ class _MatchDepositsState extends State<_MatchDeposits> {
List<InvoiceEntity> _invoices; List<InvoiceEntity> _invoices;
List<InvoiceEntity> _selectedInvoices; List<InvoiceEntity> _selectedInvoices;
bool _matchExisting = false;
bool _showFilter = false; bool _showFilter = false;
String _minAmount = ''; String _minAmount = '';
String _maxAmount = ''; String _maxAmount = '';
@ -284,12 +286,24 @@ class _MatchDepositsState extends State<_MatchDeposits> {
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12),
child: BoolDropdownButton(
value: _matchExisting,
onChanged: (value) {
setState(() => _matchExisting = value);
},
enabledLabel: localization.matchPayment,
disabledLabel: localization.createPayment,
),
),
ListDivider(),
Row( Row(
children: [ children: [
Expanded( Expanded(
child: Padding( child: Padding(
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
left: 18, top: 12, right: 10, bottom: 12), left: 20, top: 12, right: 10, bottom: 12),
child: SearchText( child: SearchText(
filterController: _filterController, filterController: _filterController,
focusNode: _focusNode, focusNode: _focusNode,
@ -304,8 +318,10 @@ class _MatchDepositsState extends State<_MatchDeposits> {
updateInvoiceList(); updateInvoiceList();
}); });
}, },
placeholder: placeholder: (_matchExisting
localization.searchInvoices.replaceFirst(':count ', ''), ? localization.searchPayments
: localization.searchInvoices)
.replaceFirst(':count ', ''),
), ),
), ),
), ),
@ -477,6 +493,7 @@ class _MatchWithdrawalsState extends State<_MatchWithdrawals> {
final _vendorScrollController = ScrollController(); final _vendorScrollController = ScrollController();
final _categoryScrollController = ScrollController(); final _categoryScrollController = ScrollController();
bool _matchExisting = false;
TextEditingController _vendorFilterController; TextEditingController _vendorFilterController;
TextEditingController _categoryFilterController; TextEditingController _categoryFilterController;
FocusNode _vendorFocusNode; FocusNode _vendorFocusNode;
@ -605,6 +622,18 @@ class _MatchWithdrawalsState extends State<_MatchWithdrawals> {
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12),
child: BoolDropdownButton(
value: _matchExisting,
onChanged: (value) {
setState(() => _matchExisting = value);
},
enabledLabel: localization.matchExpense,
disabledLabel: localization.createExpense,
),
),
ListDivider(),
Expanded( Expanded(
child: Column( child: Column(
children: [ children: [
@ -613,7 +642,7 @@ class _MatchWithdrawalsState extends State<_MatchWithdrawals> {
Expanded( Expanded(
child: Padding( child: Padding(
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
left: 18, top: 12, right: 10, bottom: 12), left: 20, top: 12, right: 10, bottom: 12),
child: SearchText( child: SearchText(
filterController: _vendorFilterController, filterController: _vendorFilterController,
focusNode: _vendorFocusNode, focusNode: _vendorFocusNode,
@ -700,7 +729,7 @@ class _MatchWithdrawalsState extends State<_MatchWithdrawals> {
Expanded( Expanded(
child: Padding( child: Padding(
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
left: 18, top: 12, right: 10, bottom: 12), left: 20, top: 12, right: 10, bottom: 12),
child: SearchText( child: SearchText(
filterController: _categoryFilterController, filterController: _categoryFilterController,
focusNode: _categoryFocusNode, focusNode: _categoryFocusNode,

View File

@ -16,8 +16,11 @@ mixin LocalizationsProvider on LocaleCodeAware {
static final Map<String, Map<String, String>> _localizedValues = { static final Map<String, Map<String, String>> _localizedValues = {
'en': { 'en': {
// STARTER: lang key - do not remove comment // STARTER: lang key - do not remove comment
'match_payment': 'Match Payment',
'match_expense': 'Match Expense',
'lock_invoiced_tasks': 'Lock Invoiced Tasks', 'lock_invoiced_tasks': 'Lock Invoiced Tasks',
'lock_invoiced_tasks_help': 'Prevent tasks from being edited once invoiced', 'lock_invoiced_tasks_help':
'Prevent tasks from being edited once invoiced',
'registration_required': 'Registration Required', 'registration_required': 'Registration Required',
'registration_required_help': 'Require clients to register', 'registration_required_help': 'Require clients to register',
'use_inventory_management': 'Use Inventory Management', 'use_inventory_management': 'Use Inventory Management',
@ -90617,6 +90620,14 @@ mixin LocalizationsProvider on LocaleCodeAware {
_localizedValues[localeCode]['lock_invoiced_tasks_help'] ?? _localizedValues[localeCode]['lock_invoiced_tasks_help'] ??
_localizedValues['en']['lock_invoiced_tasks_help']; _localizedValues['en']['lock_invoiced_tasks_help'];
String get matchPayment =>
_localizedValues[localeCode]['match_payment'] ??
_localizedValues['en']['match_payment'];
String get matchExpense =>
_localizedValues[localeCode]['match_expense'] ??
_localizedValues['en']['match_expense'];
// STARTER: lang field - do not remove comment // STARTER: lang field - do not remove comment
String lookup(String key) { String lookup(String key) {