Transaction rules

This commit is contained in:
Hillel Coren 2022-11-20 16:51:09 +02:00
parent a0cd88e25b
commit d7921fe92a
39 changed files with 3393 additions and 16 deletions

View File

@ -42,6 +42,8 @@ class EntityType extends EnumClass {
static const EntityType invoiceItem = _$invoiceItem;
static const EntityType design = _$design;
// STARTER: entity type - do not remove comment
static const EntityType transactionRule = _$transactionRule;
static const EntityType transaction = _$transaction;
static const EntityType bankAccount = _$bankAccount;

View File

@ -30,6 +30,7 @@ const EntityType _$gateway = const EntityType._('gateway');
const EntityType _$gatewayToken = const EntityType._('gatewayToken');
const EntityType _$invoiceItem = const EntityType._('invoiceItem');
const EntityType _$design = const EntityType._('design');
const EntityType _$transactionRule = const EntityType._('transactionRule');
const EntityType _$transaction = const EntityType._('transaction');
const EntityType _$bankAccount = const EntityType._('bankAccount');
const EntityType _$recurringExpense = const EntityType._('recurringExpense');
@ -103,6 +104,8 @@ EntityType _$typeValueOf(String name) {
return _$invoiceItem;
case 'design':
return _$design;
case 'transactionRule':
return _$transactionRule;
case 'transaction':
return _$transaction;
case 'bankAccount':
@ -178,6 +181,7 @@ final BuiltSet<EntityType> _$typeValues =
_$gatewayToken,
_$invoiceItem,
_$design,
_$transactionRule,
_$transaction,
_$bankAccount,
_$recurringExpense,

View File

@ -42,6 +42,7 @@ export 'package:invoiceninja_flutter/data/models/vendor_model.dart';
export 'package:invoiceninja_flutter/data/models/bank_account_model.dart';
export 'package:invoiceninja_flutter/data/models/transaction_model.dart';
// STARTER: export - do not remove comment
export 'package:invoiceninja_flutter/data/models/transaction_rule_model.dart';
part 'models.g.dart';

View File

@ -51,6 +51,7 @@ import 'package:invoiceninja_flutter/redux/webhook/webhook_state.dart';
import 'package:invoiceninja_flutter/redux/transaction/transaction_state.dart';
import 'package:invoiceninja_flutter/redux/bank_account/bank_account_state.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/redux/transaction_rule/transaction_rule_state.dart';
part 'serializers.g.dart';
@ -115,6 +116,10 @@ part 'serializers.g.dart';
TaxRateItemResponse,
TaxRateListResponse,
// STARTER: serializers - do not remove comment
TransactionRuleEntity,
TransactionRuleListResponse,
TransactionRuleItemResponse,
TransactionEntity,
TransactionListResponse,
TransactionItemResponse,

View File

@ -196,6 +196,11 @@ Serializers _$serializers = (new Serializers().toBuilder()
..add(TransactionEntity.serializer)
..add(TransactionItemResponse.serializer)
..add(TransactionListResponse.serializer)
..add(TransactionRuleEntity.serializer)
..add(TransactionRuleItemResponse.serializer)
..add(TransactionRuleListResponse.serializer)
..add(TransactionRuleState.serializer)
..add(TransactionRuleUIState.serializer)
..add(TransactionState.serializer)
..add(TransactionStatusEntity.serializer)
..add(TransactionUIState.serializer)
@ -563,6 +568,10 @@ Serializers _$serializers = (new Serializers().toBuilder()
..addBuilderFactory(
const FullType(BuiltList, const [const FullType(TransactionEntity)]),
() => new ListBuilder<TransactionEntity>())
..addBuilderFactory(
const FullType(
BuiltList, const [const FullType(TransactionRuleEntity)]),
() => new ListBuilder<TransactionRuleEntity>())
..addBuilderFactory(
const FullType(BuiltList, const [const FullType(UserCompanyEntity)]),
() => new ListBuilder<UserCompanyEntity>())
@ -918,6 +927,15 @@ Serializers _$serializers = (new Serializers().toBuilder()
..addBuilderFactory(
const FullType(BuiltList, const [const FullType(String)]),
() => new ListBuilder<String>())
..addBuilderFactory(
const FullType(BuiltMap, const [
const FullType(String),
const FullType(TransactionRuleEntity)
]),
() => new MapBuilder<String, TransactionRuleEntity>())
..addBuilderFactory(
const FullType(BuiltList, const [const FullType(String)]),
() => new ListBuilder<String>())
..addBuilderFactory(
const FullType(BuiltMap,
const [const FullType(String), const FullType(UserEntity)]),

View File

@ -0,0 +1,162 @@
import 'package:built_value/built_value.dart';
import 'package:built_collection/built_collection.dart';
import 'package:built_value/serializer.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/utils/formatting.dart';
import 'package:invoiceninja_flutter/utils/strings.dart';
part 'transaction_rule_model.g.dart';
abstract class TransactionRuleListResponse
implements
Built<TransactionRuleListResponse, TransactionRuleListResponseBuilder> {
factory TransactionRuleListResponse(
[void updates(TransactionRuleListResponseBuilder b)]) =
_$TransactionRuleListResponse;
TransactionRuleListResponse._();
@override
@memoized
int get hashCode;
BuiltList<TransactionRuleEntity> get data;
static Serializer<TransactionRuleListResponse> get serializer =>
_$transactionRuleListResponseSerializer;
}
abstract class TransactionRuleItemResponse
implements
Built<TransactionRuleItemResponse, TransactionRuleItemResponseBuilder> {
factory TransactionRuleItemResponse(
[void updates(TransactionRuleItemResponseBuilder b)]) =
_$TransactionRuleItemResponse;
TransactionRuleItemResponse._();
@override
@memoized
int get hashCode;
TransactionRuleEntity get data;
static Serializer<TransactionRuleItemResponse> get serializer =>
_$transactionRuleItemResponseSerializer;
}
class TransactionRuleFields {
static const String name = 'name';
}
abstract class TransactionRuleEntity extends Object
with BaseEntity
implements Built<TransactionRuleEntity, TransactionRuleEntityBuilder> {
factory TransactionRuleEntity({String id, AppState state}) {
return _$TransactionRuleEntity._(
id: id ?? BaseEntity.nextId,
isChanged: false,
isDeleted: false,
createdAt: 0,
updatedAt: 0,
createdUserId: '',
assignedUserId: '',
archivedAt: 0,
// STARTER: constructor - do not remove comment
transaction_rules: '',
);
}
TransactionRuleEntity._();
@override
@memoized
int get hashCode;
// STARTER: properties - do not remove comment
String get name;
@override
EntityType get entityType => EntityType.transactionRule;
@override
List<EntityAction> getActions(
{UserCompanyEntity userCompany,
ClientEntity client,
bool includeEdit = false,
bool multiselect = false}) {
final actions = <EntityAction>[];
if (!isDeleted &&
!multiselect &&
includeEdit &&
userCompany.canEditEntity(this)) {
actions.add(EntityAction.edit);
}
if (actions.isNotEmpty && actions.last != null) {
actions.add(null);
}
return actions..addAll(super.getActions(userCompany: userCompany));
}
int compareTo(TransactionRuleEntity transactionRule, String sortField,
bool sortAscending) {
int response = 0;
final transactionRuleA = sortAscending ? this : transactionRule;
final transactionRuleB = sortAscending ? transactionRule : this;
switch (sortField) {
// STARTER: sort switch - do not remove comment
case TransactionRuleFields.transaction_rules:
response = transactionRuleA.name.compareTo(transactionRuleB.name);
break;
default:
print(
'## ERROR: sort by transactionRule.$sortField is not implemented');
break;
}
if (response == 0) {
// STARTER: sort default - do not remove comment
return transactionRuleA.name.compareTo(transactionRuleB.name);
} else {
return response;
}
}
@override
bool matchesFilter(String filter) {
return matchesStrings(
haystacks: [
//
],
needle: filter,
);
}
@override
String matchesFilterValue(String filter) {
return matchesStringsValue(
haystacks: [
//
],
needle: filter,
);
}
@override
String get listDisplayName => null;
@override
double get listDisplayAmount => null;
@override
FormatNumberType get listDisplayAmountType => null;
static Serializer<TransactionRuleEntity> get serializer =>
_$transactionRuleEntitySerializer;
}

View File

@ -0,0 +1,622 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'transaction_rule_model.dart';
// **************************************************************************
// BuiltValueGenerator
// **************************************************************************
Serializer<TransactionRuleListResponse>
_$transactionRuleListResponseSerializer =
new _$TransactionRuleListResponseSerializer();
Serializer<TransactionRuleItemResponse>
_$transactionRuleItemResponseSerializer =
new _$TransactionRuleItemResponseSerializer();
Serializer<TransactionRuleEntity> _$transactionRuleEntitySerializer =
new _$TransactionRuleEntitySerializer();
class _$TransactionRuleListResponseSerializer
implements StructuredSerializer<TransactionRuleListResponse> {
@override
final Iterable<Type> types = const [
TransactionRuleListResponse,
_$TransactionRuleListResponse
];
@override
final String wireName = 'TransactionRuleListResponse';
@override
Iterable<Object> serialize(
Serializers serializers, TransactionRuleListResponse object,
{FullType specifiedType = FullType.unspecified}) {
final result = <Object>[
'data',
serializers.serialize(object.data,
specifiedType: const FullType(
BuiltList, const [const FullType(TransactionRuleEntity)])),
];
return result;
}
@override
TransactionRuleListResponse deserialize(
Serializers serializers, Iterable<Object> serialized,
{FullType specifiedType = FullType.unspecified}) {
final result = new TransactionRuleListResponseBuilder();
final iterator = serialized.iterator;
while (iterator.moveNext()) {
final key = iterator.current as String;
iterator.moveNext();
final Object value = iterator.current;
switch (key) {
case 'data':
result.data.replace(serializers.deserialize(value,
specifiedType: const FullType(
BuiltList, const [const FullType(TransactionRuleEntity)]))
as BuiltList<Object>);
break;
}
}
return result.build();
}
}
class _$TransactionRuleItemResponseSerializer
implements StructuredSerializer<TransactionRuleItemResponse> {
@override
final Iterable<Type> types = const [
TransactionRuleItemResponse,
_$TransactionRuleItemResponse
];
@override
final String wireName = 'TransactionRuleItemResponse';
@override
Iterable<Object> serialize(
Serializers serializers, TransactionRuleItemResponse object,
{FullType specifiedType = FullType.unspecified}) {
final result = <Object>[
'data',
serializers.serialize(object.data,
specifiedType: const FullType(TransactionRuleEntity)),
];
return result;
}
@override
TransactionRuleItemResponse deserialize(
Serializers serializers, Iterable<Object> serialized,
{FullType specifiedType = FullType.unspecified}) {
final result = new TransactionRuleItemResponseBuilder();
final iterator = serialized.iterator;
while (iterator.moveNext()) {
final key = iterator.current as String;
iterator.moveNext();
final Object value = iterator.current;
switch (key) {
case 'data':
result.data.replace(serializers.deserialize(value,
specifiedType: const FullType(TransactionRuleEntity))
as TransactionRuleEntity);
break;
}
}
return result.build();
}
}
class _$TransactionRuleEntitySerializer
implements StructuredSerializer<TransactionRuleEntity> {
@override
final Iterable<Type> types = const [
TransactionRuleEntity,
_$TransactionRuleEntity
];
@override
final String wireName = 'TransactionRuleEntity';
@override
Iterable<Object> serialize(
Serializers serializers, TransactionRuleEntity object,
{FullType specifiedType = FullType.unspecified}) {
final result = <Object>[
'name',
serializers.serialize(object.name, specifiedType: const FullType(String)),
'created_at',
serializers.serialize(object.createdAt,
specifiedType: const FullType(int)),
'updated_at',
serializers.serialize(object.updatedAt,
specifiedType: const FullType(int)),
'archived_at',
serializers.serialize(object.archivedAt,
specifiedType: const FullType(int)),
'id',
serializers.serialize(object.id, specifiedType: const FullType(String)),
];
Object value;
value = object.isChanged;
if (value != null) {
result
..add('isChanged')
..add(
serializers.serialize(value, specifiedType: const FullType(bool)));
}
value = object.isDeleted;
if (value != null) {
result
..add('is_deleted')
..add(
serializers.serialize(value, specifiedType: const FullType(bool)));
}
value = object.createdUserId;
if (value != null) {
result
..add('user_id')
..add(serializers.serialize(value,
specifiedType: const FullType(String)));
}
value = object.assignedUserId;
if (value != null) {
result
..add('assigned_user_id')
..add(serializers.serialize(value,
specifiedType: const FullType(String)));
}
return result;
}
@override
TransactionRuleEntity deserialize(
Serializers serializers, Iterable<Object> serialized,
{FullType specifiedType = FullType.unspecified}) {
final result = new TransactionRuleEntityBuilder();
final iterator = serialized.iterator;
while (iterator.moveNext()) {
final key = iterator.current as String;
iterator.moveNext();
final Object value = iterator.current;
switch (key) {
case 'name':
result.name = serializers.deserialize(value,
specifiedType: const FullType(String)) as String;
break;
case 'isChanged':
result.isChanged = serializers.deserialize(value,
specifiedType: const FullType(bool)) as bool;
break;
case 'created_at':
result.createdAt = serializers.deserialize(value,
specifiedType: const FullType(int)) as int;
break;
case 'updated_at':
result.updatedAt = serializers.deserialize(value,
specifiedType: const FullType(int)) as int;
break;
case 'archived_at':
result.archivedAt = serializers.deserialize(value,
specifiedType: const FullType(int)) as int;
break;
case 'is_deleted':
result.isDeleted = serializers.deserialize(value,
specifiedType: const FullType(bool)) as bool;
break;
case 'user_id':
result.createdUserId = serializers.deserialize(value,
specifiedType: const FullType(String)) as String;
break;
case 'assigned_user_id':
result.assignedUserId = serializers.deserialize(value,
specifiedType: const FullType(String)) as String;
break;
case 'id':
result.id = serializers.deserialize(value,
specifiedType: const FullType(String)) as String;
break;
}
}
return result.build();
}
}
class _$TransactionRuleListResponse extends TransactionRuleListResponse {
@override
final BuiltList<TransactionRuleEntity> data;
factory _$TransactionRuleListResponse(
[void Function(TransactionRuleListResponseBuilder) updates]) =>
(new TransactionRuleListResponseBuilder()..update(updates)).build();
_$TransactionRuleListResponse._({this.data}) : super._() {
BuiltValueNullFieldError.checkNotNull(
data, 'TransactionRuleListResponse', 'data');
}
@override
TransactionRuleListResponse rebuild(
void Function(TransactionRuleListResponseBuilder) updates) =>
(toBuilder()..update(updates)).build();
@override
TransactionRuleListResponseBuilder toBuilder() =>
new TransactionRuleListResponseBuilder()..replace(this);
@override
bool operator ==(Object other) {
if (identical(other, this)) return true;
return other is TransactionRuleListResponse && data == other.data;
}
int __hashCode;
@override
int get hashCode {
return __hashCode ??= $jf($jc(0, data.hashCode));
}
@override
String toString() {
return (newBuiltValueToStringHelper('TransactionRuleListResponse')
..add('data', data))
.toString();
}
}
class TransactionRuleListResponseBuilder
implements
Builder<TransactionRuleListResponse,
TransactionRuleListResponseBuilder> {
_$TransactionRuleListResponse _$v;
ListBuilder<TransactionRuleEntity> _data;
ListBuilder<TransactionRuleEntity> get data =>
_$this._data ??= new ListBuilder<TransactionRuleEntity>();
set data(ListBuilder<TransactionRuleEntity> data) => _$this._data = data;
TransactionRuleListResponseBuilder();
TransactionRuleListResponseBuilder get _$this {
final $v = _$v;
if ($v != null) {
_data = $v.data.toBuilder();
_$v = null;
}
return this;
}
@override
void replace(TransactionRuleListResponse other) {
ArgumentError.checkNotNull(other, 'other');
_$v = other as _$TransactionRuleListResponse;
}
@override
void update(void Function(TransactionRuleListResponseBuilder) updates) {
if (updates != null) updates(this);
}
@override
_$TransactionRuleListResponse build() {
_$TransactionRuleListResponse _$result;
try {
_$result = _$v ?? new _$TransactionRuleListResponse._(data: data.build());
} catch (_) {
String _$failedField;
try {
_$failedField = 'data';
data.build();
} catch (e) {
throw new BuiltValueNestedFieldError(
'TransactionRuleListResponse', _$failedField, e.toString());
}
rethrow;
}
replace(_$result);
return _$result;
}
}
class _$TransactionRuleItemResponse extends TransactionRuleItemResponse {
@override
final TransactionRuleEntity data;
factory _$TransactionRuleItemResponse(
[void Function(TransactionRuleItemResponseBuilder) updates]) =>
(new TransactionRuleItemResponseBuilder()..update(updates)).build();
_$TransactionRuleItemResponse._({this.data}) : super._() {
BuiltValueNullFieldError.checkNotNull(
data, 'TransactionRuleItemResponse', 'data');
}
@override
TransactionRuleItemResponse rebuild(
void Function(TransactionRuleItemResponseBuilder) updates) =>
(toBuilder()..update(updates)).build();
@override
TransactionRuleItemResponseBuilder toBuilder() =>
new TransactionRuleItemResponseBuilder()..replace(this);
@override
bool operator ==(Object other) {
if (identical(other, this)) return true;
return other is TransactionRuleItemResponse && data == other.data;
}
int __hashCode;
@override
int get hashCode {
return __hashCode ??= $jf($jc(0, data.hashCode));
}
@override
String toString() {
return (newBuiltValueToStringHelper('TransactionRuleItemResponse')
..add('data', data))
.toString();
}
}
class TransactionRuleItemResponseBuilder
implements
Builder<TransactionRuleItemResponse,
TransactionRuleItemResponseBuilder> {
_$TransactionRuleItemResponse _$v;
TransactionRuleEntityBuilder _data;
TransactionRuleEntityBuilder get data =>
_$this._data ??= new TransactionRuleEntityBuilder();
set data(TransactionRuleEntityBuilder data) => _$this._data = data;
TransactionRuleItemResponseBuilder();
TransactionRuleItemResponseBuilder get _$this {
final $v = _$v;
if ($v != null) {
_data = $v.data.toBuilder();
_$v = null;
}
return this;
}
@override
void replace(TransactionRuleItemResponse other) {
ArgumentError.checkNotNull(other, 'other');
_$v = other as _$TransactionRuleItemResponse;
}
@override
void update(void Function(TransactionRuleItemResponseBuilder) updates) {
if (updates != null) updates(this);
}
@override
_$TransactionRuleItemResponse build() {
_$TransactionRuleItemResponse _$result;
try {
_$result = _$v ?? new _$TransactionRuleItemResponse._(data: data.build());
} catch (_) {
String _$failedField;
try {
_$failedField = 'data';
data.build();
} catch (e) {
throw new BuiltValueNestedFieldError(
'TransactionRuleItemResponse', _$failedField, e.toString());
}
rethrow;
}
replace(_$result);
return _$result;
}
}
class _$TransactionRuleEntity extends TransactionRuleEntity {
@override
final String name;
@override
final bool isChanged;
@override
final int createdAt;
@override
final int updatedAt;
@override
final int archivedAt;
@override
final bool isDeleted;
@override
final String createdUserId;
@override
final String assignedUserId;
@override
final String id;
factory _$TransactionRuleEntity(
[void Function(TransactionRuleEntityBuilder) updates]) =>
(new TransactionRuleEntityBuilder()..update(updates)).build();
_$TransactionRuleEntity._(
{this.name,
this.isChanged,
this.createdAt,
this.updatedAt,
this.archivedAt,
this.isDeleted,
this.createdUserId,
this.assignedUserId,
this.id})
: super._() {
BuiltValueNullFieldError.checkNotNull(
name, 'TransactionRuleEntity', 'name');
BuiltValueNullFieldError.checkNotNull(
createdAt, 'TransactionRuleEntity', 'createdAt');
BuiltValueNullFieldError.checkNotNull(
updatedAt, 'TransactionRuleEntity', 'updatedAt');
BuiltValueNullFieldError.checkNotNull(
archivedAt, 'TransactionRuleEntity', 'archivedAt');
BuiltValueNullFieldError.checkNotNull(id, 'TransactionRuleEntity', 'id');
}
@override
TransactionRuleEntity rebuild(
void Function(TransactionRuleEntityBuilder) updates) =>
(toBuilder()..update(updates)).build();
@override
TransactionRuleEntityBuilder toBuilder() =>
new TransactionRuleEntityBuilder()..replace(this);
@override
bool operator ==(Object other) {
if (identical(other, this)) return true;
return other is TransactionRuleEntity &&
name == other.name &&
isChanged == other.isChanged &&
createdAt == other.createdAt &&
updatedAt == other.updatedAt &&
archivedAt == other.archivedAt &&
isDeleted == other.isDeleted &&
createdUserId == other.createdUserId &&
assignedUserId == other.assignedUserId &&
id == other.id;
}
int __hashCode;
@override
int get hashCode {
return __hashCode ??= $jf($jc(
$jc(
$jc(
$jc(
$jc(
$jc(
$jc($jc($jc(0, name.hashCode), isChanged.hashCode),
createdAt.hashCode),
updatedAt.hashCode),
archivedAt.hashCode),
isDeleted.hashCode),
createdUserId.hashCode),
assignedUserId.hashCode),
id.hashCode));
}
@override
String toString() {
return (newBuiltValueToStringHelper('TransactionRuleEntity')
..add('name', name)
..add('isChanged', isChanged)
..add('createdAt', createdAt)
..add('updatedAt', updatedAt)
..add('archivedAt', archivedAt)
..add('isDeleted', isDeleted)
..add('createdUserId', createdUserId)
..add('assignedUserId', assignedUserId)
..add('id', id))
.toString();
}
}
class TransactionRuleEntityBuilder
implements Builder<TransactionRuleEntity, TransactionRuleEntityBuilder> {
_$TransactionRuleEntity _$v;
String _name;
String get name => _$this._name;
set name(String name) => _$this._name = name;
bool _isChanged;
bool get isChanged => _$this._isChanged;
set isChanged(bool isChanged) => _$this._isChanged = isChanged;
int _createdAt;
int get createdAt => _$this._createdAt;
set createdAt(int createdAt) => _$this._createdAt = createdAt;
int _updatedAt;
int get updatedAt => _$this._updatedAt;
set updatedAt(int updatedAt) => _$this._updatedAt = updatedAt;
int _archivedAt;
int get archivedAt => _$this._archivedAt;
set archivedAt(int archivedAt) => _$this._archivedAt = archivedAt;
bool _isDeleted;
bool get isDeleted => _$this._isDeleted;
set isDeleted(bool isDeleted) => _$this._isDeleted = isDeleted;
String _createdUserId;
String get createdUserId => _$this._createdUserId;
set createdUserId(String createdUserId) =>
_$this._createdUserId = createdUserId;
String _assignedUserId;
String get assignedUserId => _$this._assignedUserId;
set assignedUserId(String assignedUserId) =>
_$this._assignedUserId = assignedUserId;
String _id;
String get id => _$this._id;
set id(String id) => _$this._id = id;
TransactionRuleEntityBuilder();
TransactionRuleEntityBuilder get _$this {
final $v = _$v;
if ($v != null) {
_name = $v.name;
_isChanged = $v.isChanged;
_createdAt = $v.createdAt;
_updatedAt = $v.updatedAt;
_archivedAt = $v.archivedAt;
_isDeleted = $v.isDeleted;
_createdUserId = $v.createdUserId;
_assignedUserId = $v.assignedUserId;
_id = $v.id;
_$v = null;
}
return this;
}
@override
void replace(TransactionRuleEntity other) {
ArgumentError.checkNotNull(other, 'other');
_$v = other as _$TransactionRuleEntity;
}
@override
void update(void Function(TransactionRuleEntityBuilder) updates) {
if (updates != null) updates(this);
}
@override
_$TransactionRuleEntity build() {
final _$result = _$v ??
new _$TransactionRuleEntity._(
name: BuiltValueNullFieldError.checkNotNull(
name, 'TransactionRuleEntity', 'name'),
isChanged: isChanged,
createdAt: BuiltValueNullFieldError.checkNotNull(
createdAt, 'TransactionRuleEntity', 'createdAt'),
updatedAt: BuiltValueNullFieldError.checkNotNull(
updatedAt, 'TransactionRuleEntity', 'updatedAt'),
archivedAt: BuiltValueNullFieldError.checkNotNull(
archivedAt, 'TransactionRuleEntity', 'archivedAt'),
isDeleted: isDeleted,
createdUserId: createdUserId,
assignedUserId: assignedUserId,
id: BuiltValueNullFieldError.checkNotNull(
id, 'TransactionRuleEntity', 'id'));
replace(_$result);
return _$result;
}
}
// ignore_for_file: always_put_control_body_on_new_line,always_specify_types,annotate_overrides,avoid_annotating_with_dynamic,avoid_as,avoid_catches_without_on_clauses,avoid_returning_this,deprecated_member_use_from_same_package,lines_longer_than_80_chars,omit_local_variable_types,prefer_expression_function_bodies,sort_constructors_first,test_types_in_equals,unnecessary_const,unnecessary_new

View File

@ -0,0 +1,77 @@
import 'dart:convert';
import 'dart:core';
import 'package:built_collection/built_collection.dart';
import 'package:invoiceninja_flutter/constants.dart';
import 'package:invoiceninja_flutter/data/models/serializers.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/data/web_client.dart';
class TransactionRuleRepository {
const TransactionRuleRepository({
this.webClient = const WebClient(),
});
final WebClient webClient;
Future<TransactionRuleEntity> loadItem(
Credentials credentials, String entityId) async {
final dynamic response = await webClient.get(
'${credentials.url}/transaction_rules/$entityId', credentials.token);
final TransactionRuleItemResponse transactionRuleResponse = serializers
.deserializeWith(TransactionRuleItemResponse.serializer, response);
return transactionRuleResponse.data;
}
Future<BuiltList<TransactionRuleEntity>> loadList(
Credentials credentials) async {
final String url = credentials.url + '/transaction_rules?';
final dynamic response = await webClient.get(url, credentials.token);
final TransactionRuleListResponse transactionRuleResponse = serializers
.deserializeWith(TransactionRuleListResponse.serializer, response);
return transactionRuleResponse.data;
}
Future<List<TransactionRuleEntity>> bulkAction(
Credentials credentials, List<String> ids, EntityAction action) async {
if (ids.length > kMaxEntitiesPerBulkAction) {
ids = ids.sublist(0, kMaxEntitiesPerBulkAction);
}
final url = credentials.url +
'/transaction_rules/bulk?per_page=$kMaxEntitiesPerBulkAction';
final dynamic response = await webClient.post(url, credentials.token,
data: json.encode({'ids': ids, 'action': action.toApiParam()}));
final TransactionRuleListResponse transactionRuleResponse = serializers
.deserializeWith(TransactionRuleListResponse.serializer, response);
return transactionRuleResponse.data.toList();
}
Future<TransactionRuleEntity> saveData(
Credentials credentials, TransactionRuleEntity transactionRule) async {
final data = serializers.serializeWith(
TransactionRuleEntity.serializer, transactionRule);
dynamic response;
if (transactionRule.isNew) {
response = await webClient.post(
credentials.url + '/transaction_rules', credentials.token,
data: json.encode(data));
} else {
final url = '${credentials.url}/transaction_rules/${transactionRule.id}';
response =
await webClient.put(url, credentials.token, data: json.encode(data));
}
final TransactionRuleItemResponse transactionRuleResponse = serializers
.deserializeWith(TransactionRuleItemResponse.serializer, response);
return transactionRuleResponse.data;
}
}

View File

@ -142,6 +142,7 @@ void main({bool isTesting = false}) async {
..addAll(createStoreSettingsMiddleware())
..addAll(createStoreReportsMiddleware())
// STARTER: middleware - do not remove comment
..addAll(createStoreTransactionRulesMiddleware())
..addAll(createStoreTransactionsMiddleware())
..addAll(createStoreBankAccountsMiddleware())
..addAll(createStorePurchaseOrdersMiddleware())

View File

@ -98,6 +98,11 @@ import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/utils/platforms.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/ui/transaction_rule/transaction_rule_screen.dart';
import 'package:invoiceninja_flutter/ui/transaction_rule/edit/transaction_rule_edit_vm.dart';
import 'package:invoiceninja_flutter/ui/transaction_rule/view/transaction_rule_view_vm.dart';
import 'package:invoiceninja_flutter/ui/transaction_rule/transaction_rule_screen_vm.dart';
import 'package:invoiceninja_flutter/ui/transaction/transaction_screen.dart';
import 'package:invoiceninja_flutter/ui/transaction/edit/transaction_edit_vm.dart';
import 'package:invoiceninja_flutter/ui/transaction/view/transaction_view_vm.dart';
@ -527,6 +532,13 @@ class InvoiceNinjaAppState extends State<InvoiceNinjaApp> {
QuoteEmailScreen(),
QuotePdfScreen.route: (context) => QuotePdfScreen(),
// STARTER: routes - do not remove comment
TransactionRuleScreen.route: (context) =>
TransactionRuleScreenBuilder(),
TransactionRuleViewScreen.route: (context) =>
TransactionRuleViewScreen(),
TransactionRuleEditScreen.route: (context) =>
TransactionRuleEditScreen(),
TransactionScreen.route: (context) =>
TransactionScreenBuilder(),
TransactionViewScreen.route: (context) =>

View File

@ -65,6 +65,8 @@ import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/utils/platforms.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/redux/transaction_rule/transaction_rule_actions.dart';
import 'package:invoiceninja_flutter/redux/transaction/transaction_actions.dart';
import 'package:invoiceninja_flutter/redux/bank_account/bank_account_actions.dart';
@ -392,6 +394,10 @@ void viewEntitiesByType({
action = ViewGroupList();
break;
// STARTER: view list - do not remove comment
case EntityType.transactionRule:
action = ViewTransactionRuleList();
break;
case EntityType.transaction:
action = ViewTransactionList();
break;
@ -614,6 +620,13 @@ void viewEntityById({
));
break;
// STARTER: view - do not remove comment
case EntityType.transactionRule:
store.dispatch(ViewTransactionRule(
transactionRuleId: entityId,
force: force,
));
break;
case EntityType.transaction:
store.dispatch(ViewTransaction(
transactionId: entityId,
@ -860,6 +873,13 @@ void createEntityByType({
));
break;
// STARTER: create type - do not remove comment
case EntityType.transactionRule:
store.dispatch(EditTransactionRule(
force: force,
transactionRule: TransactionRuleEntity(state: state),
));
break;
case EntityType.transaction:
store.dispatch(EditTransaction(
force: force,
@ -1090,6 +1110,14 @@ void createEntity({
));
break;
// STARTER: create - do not remove comment
case EntityType.transactionRule:
store.dispatch(EditTransactionRule(
transactionRule: entity,
force: force,
completer: completer,
));
break;
case EntityType.transaction:
store.dispatch(EditTransaction(
transaction: entity,
@ -1301,6 +1329,11 @@ void editEntity({
));
break;
// STARTER: edit - do not remove comment
case EntityType.transactionRule:
store.dispatch(EditTransactionRule(
transactionRule: entity, completer: completer));
break;
case EntityType.transaction:
store.dispatch(
EditTransaction(transaction: entity, completer: completer));
@ -1489,6 +1522,10 @@ void handleEntitiesActions(List<BaseEntity> entities, EntityAction action,
handleDocumentAction(context, entities, action);
break;
// STARTER: actions - do not remove comment
case EntityType.transactionRule:
handleTransactionRuleAction(context, entities, action);
break;
case EntityType.transaction:
handleTransactionAction(context, entities, action);
break;

View File

@ -32,6 +32,8 @@ import 'package:invoiceninja_flutter/redux/vendor/vendor_actions.dart';
import 'package:invoiceninja_flutter/redux/webhook/webhook_actions.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/redux/transaction_rule/transaction_rule_actions.dart';
import 'package:invoiceninja_flutter/redux/transaction/transaction_actions.dart';
import 'package:invoiceninja_flutter/redux/bank_account/bank_account_actions.dart';
@ -106,6 +108,10 @@ final lastErrorReducer = combineReducers<String>([
return '${action.error}';
}),
// STARTER: errors - do not remove comment
TypedReducer<String, LoadTransactionRulesFailure>((state, action) {
return '${action.error}';
}),
TypedReducer<String, LoadTransactionsFailure>((state, action) {
return '${action.error}';
}),

View File

@ -71,6 +71,8 @@ import 'package:invoiceninja_flutter/redux/bank_account/bank_account_state.dart'
import 'package:invoiceninja_flutter/redux/purchase_order/purchase_order_state.dart';
import 'package:invoiceninja_flutter/ui/purchase_order/edit/purchase_order_edit_vm.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/redux/transaction_rule/transaction_rule_state.dart';
import 'package:invoiceninja_flutter/ui/transaction_rule/edit/transaction_rule_edit_vm.dart';
part 'app_state.g.dart';
@ -272,6 +274,9 @@ abstract class AppState implements Built<AppState, AppStateBuilder> {
case EntityType.invoice:
return invoiceState.map;
// STARTER: states switch map - do not remove comment
case EntityType.transactionRule:
return transactionRuleState.map;
case EntityType.transaction:
return transactionState.map;
@ -361,6 +366,9 @@ abstract class AppState implements Built<AppState, AppStateBuilder> {
case EntityType.invoice:
return invoiceState.list;
// STARTER: states switch list - do not remove comment
case EntityType.transactionRule:
return transactionRuleState.list;
case EntityType.transaction:
return transactionState.list;
@ -439,6 +447,9 @@ abstract class AppState implements Built<AppState, AppStateBuilder> {
case EntityType.invoice:
return invoiceUIState;
// STARTER: states switch - do not remove comment
case EntityType.transactionRule:
return transactionRuleUIState;
case EntityType.transaction:
return transactionUIState;
@ -518,6 +529,13 @@ abstract class AppState implements Built<AppState, AppStateBuilder> {
ListUIState get invoiceListState => uiState.invoiceUIState.listUIState;
// STARTER: state getters - do not remove comment
TransactionRuleState get transactionRuleState =>
userCompanyState.transactionRuleState;
ListUIState get transactionRuleListState =>
uiState.transactionRuleUIState.listUIState;
TransactionRuleUIState get transactionRuleUIState =>
uiState.transactionRuleUIState;
TransactionState get transactionState => userCompanyState.transactionState;
ListUIState get transactionListState =>
uiState.transactionUIState.listUIState;
@ -703,6 +721,9 @@ abstract class AppState implements Built<AppState, AppStateBuilder> {
case CreditEditScreen.route:
return creditUIState.editing.isChanged == true;
// STARTER: has changes - do not remove comment
case TransactionRuleEditScreen.route:
return hastransactionRuleUIState.editing.isChanged == true;
case TransactionEditScreen.route:
return transactionUIState.editing.isChanged == true;
case PurchaseOrderEditScreen.route:

View File

@ -36,6 +36,8 @@ import 'package:invoiceninja_flutter/redux/vendor/vendor_reducer.dart';
import 'package:invoiceninja_flutter/redux/webhook/webhook_reducer.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/redux/transaction_rule/transaction_rule_reducer.dart';
import 'package:invoiceninja_flutter/redux/transaction/transaction_reducer.dart';
import 'package:invoiceninja_flutter/redux/bank_account/bank_account_reducer.dart';
@ -58,6 +60,8 @@ UserCompanyState companyReducer(UserCompanyState state, dynamic action) {
..vendorState.replace(vendorsReducer(state.vendorState, action))
..taskState.replace(tasksReducer(state.taskState, action))
// STARTER: reducer - do not remove comment
..transactionRuleState
.replace(transactionRulesReducer(state.transactionRuleState, action))
..transactionState
.replace(transactionsReducer(state.transactionState, action))
..bankAccountState

View File

@ -32,6 +32,8 @@ import 'package:invoiceninja_flutter/redux/vendor/vendor_state.dart';
import 'package:invoiceninja_flutter/redux/webhook/webhook_state.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/redux/transaction_rule/transaction_rule_state.dart';
import 'package:invoiceninja_flutter/redux/transaction/transaction_state.dart';
import 'package:invoiceninja_flutter/redux/bank_account/bank_account_state.dart';
@ -57,6 +59,8 @@ abstract class UserCompanyState
paymentState: PaymentState(),
quoteState: QuoteState(),
// STARTER: constructor - do not remove comment
transactionRuleState: TransactionRuleState(),
transactionState: TransactionState(),
bankAccountState: BankAccountState(),
@ -112,6 +116,8 @@ abstract class UserCompanyState
QuoteState get quoteState;
// STARTER: fields - do not remove comment
TransactionRuleState get transactionRuleState;
TransactionState get transactionState;
BankAccountState get bankAccountState;

View File

@ -55,6 +55,9 @@ class _$UserCompanyStateSerializer
'quoteState',
serializers.serialize(object.quoteState,
specifiedType: const FullType(QuoteState)),
'transactionRuleState',
serializers.serialize(object.transactionRuleState,
specifiedType: const FullType(TransactionRuleState)),
'transactionState',
serializers.serialize(object.transactionState,
specifiedType: const FullType(TransactionState)),
@ -179,6 +182,11 @@ class _$UserCompanyStateSerializer
result.quoteState.replace(serializers.deserialize(value,
specifiedType: const FullType(QuoteState)) as QuoteState);
break;
case 'transactionRuleState':
result.transactionRuleState.replace(serializers.deserialize(value,
specifiedType: const FullType(TransactionRuleState))
as TransactionRuleState);
break;
case 'transactionState':
result.transactionState.replace(serializers.deserialize(value,
specifiedType: const FullType(TransactionState))
@ -441,6 +449,8 @@ class _$UserCompanyState extends UserCompanyState {
@override
final QuoteState quoteState;
@override
final TransactionRuleState transactionRuleState;
@override
final TransactionState transactionState;
@override
final BankAccountState bankAccountState;
@ -492,6 +502,7 @@ class _$UserCompanyState extends UserCompanyState {
this.projectState,
this.paymentState,
this.quoteState,
this.transactionRuleState,
this.transactionState,
this.bankAccountState,
this.purchaseOrderState,
@ -532,6 +543,8 @@ class _$UserCompanyState extends UserCompanyState {
paymentState, 'UserCompanyState', 'paymentState');
BuiltValueNullFieldError.checkNotNull(
quoteState, 'UserCompanyState', 'quoteState');
BuiltValueNullFieldError.checkNotNull(
transactionRuleState, 'UserCompanyState', 'transactionRuleState');
BuiltValueNullFieldError.checkNotNull(
transactionState, 'UserCompanyState', 'transactionState');
BuiltValueNullFieldError.checkNotNull(
@ -592,6 +605,7 @@ class _$UserCompanyState extends UserCompanyState {
projectState == other.projectState &&
paymentState == other.paymentState &&
quoteState == other.quoteState &&
transactionRuleState == other.transactionRuleState &&
transactionState == other.transactionState &&
bankAccountState == other.bankAccountState &&
purchaseOrderState == other.purchaseOrderState &&
@ -632,9 +646,9 @@ class _$UserCompanyState extends UserCompanyState {
$jc(
$jc(
$jc(
$jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc(0, lastUpdated.hashCode), userCompany.hashCode), documentState.hashCode), productState.hashCode), clientState.hashCode), invoiceState.hashCode), expenseState.hashCode), vendorState.hashCode), taskState.hashCode), projectState.hashCode),
paymentState.hashCode),
quoteState.hashCode),
$jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc(0, lastUpdated.hashCode), userCompany.hashCode), documentState.hashCode), productState.hashCode), clientState.hashCode), invoiceState.hashCode), expenseState.hashCode), vendorState.hashCode), taskState.hashCode), projectState.hashCode), paymentState.hashCode),
quoteState.hashCode),
transactionRuleState.hashCode),
transactionState.hashCode),
bankAccountState.hashCode),
purchaseOrderState.hashCode),
@ -669,6 +683,7 @@ class _$UserCompanyState extends UserCompanyState {
..add('projectState', projectState)
..add('paymentState', paymentState)
..add('quoteState', quoteState)
..add('transactionRuleState', transactionRuleState)
..add('transactionState', transactionState)
..add('bankAccountState', bankAccountState)
..add('purchaseOrderState', purchaseOrderState)
@ -763,6 +778,12 @@ class UserCompanyStateBuilder
set quoteState(QuoteStateBuilder quoteState) =>
_$this._quoteState = quoteState;
TransactionRuleStateBuilder _transactionRuleState;
TransactionRuleStateBuilder get transactionRuleState =>
_$this._transactionRuleState ??= new TransactionRuleStateBuilder();
set transactionRuleState(TransactionRuleStateBuilder transactionRuleState) =>
_$this._transactionRuleState = transactionRuleState;
TransactionStateBuilder _transactionState;
TransactionStateBuilder get transactionState =>
_$this._transactionState ??= new TransactionStateBuilder();
@ -883,6 +904,7 @@ class UserCompanyStateBuilder
_projectState = $v.projectState.toBuilder();
_paymentState = $v.paymentState.toBuilder();
_quoteState = $v.quoteState.toBuilder();
_transactionRuleState = $v.transactionRuleState.toBuilder();
_transactionState = $v.transactionState.toBuilder();
_bankAccountState = $v.bankAccountState.toBuilder();
_purchaseOrderState = $v.purchaseOrderState.toBuilder();
@ -935,6 +957,7 @@ class UserCompanyStateBuilder
projectState: projectState.build(),
paymentState: paymentState.build(),
quoteState: quoteState.build(),
transactionRuleState: transactionRuleState.build(),
transactionState: transactionState.build(),
bankAccountState: bankAccountState.build(),
purchaseOrderState: purchaseOrderState.build(),
@ -977,6 +1000,8 @@ class UserCompanyStateBuilder
paymentState.build();
_$failedField = 'quoteState';
quoteState.build();
_$failedField = 'transactionRuleState';
transactionRuleState.build();
_$failedField = 'transactionState';
transactionState.build();
_$failedField = 'bankAccountState';

View File

@ -0,0 +1,327 @@
import 'dart:async';
import 'package:built_collection/built_collection.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/ui/app/entities/entity_actions_dialog.dart';
class ViewTransactionRuleList implements PersistUI {
ViewTransactionRuleList({this.force = false});
final bool force;
}
class ViewTransactionRule implements PersistUI, PersistPrefs {
ViewTransactionRule({
@required this.transactionRuleId,
this.force = false,
});
final String transactionRuleId;
final bool force;
}
class EditTransactionRule implements PersistUI, PersistPrefs {
EditTransactionRule(
{@required this.transactionRule,
this.completer,
this.cancelCompleter,
this.force = false});
final TransactionRuleEntity transactionRule;
final Completer completer;
final Completer cancelCompleter;
final bool force;
}
class UpdateTransactionRule implements PersistUI {
UpdateTransactionRule(this.transactionRule);
final TransactionRuleEntity transactionRule;
}
class LoadTransactionRule {
LoadTransactionRule({this.completer, this.transactionRuleId});
final Completer completer;
final String transactionRuleId;
}
class LoadTransactionRuleActivity {
LoadTransactionRuleActivity({this.completer, this.transactionRuleId});
final Completer completer;
final String transactionRuleId;
}
class LoadTransactionRules {
LoadTransactionRules({this.completer});
final Completer completer;
}
class LoadTransactionRuleRequest implements StartLoading {}
class LoadTransactionRuleFailure implements StopLoading {
LoadTransactionRuleFailure(this.error);
final dynamic error;
@override
String toString() {
return 'LoadTransactionRuleFailure{error: $error}';
}
}
class LoadTransactionRuleSuccess implements StopLoading, PersistData {
LoadTransactionRuleSuccess(this.transactionRule);
final TransactionRuleEntity transactionRule;
@override
String toString() {
return 'LoadTransactionRuleSuccess{transactionRule: $transactionRule}';
}
}
class LoadTransactionRulesRequest implements StartLoading {}
class LoadTransactionRulesFailure implements StopLoading {
LoadTransactionRulesFailure(this.error);
final dynamic error;
@override
String toString() {
return 'LoadTransactionRulesFailure{error: $error}';
}
}
class LoadTransactionRulesSuccess implements StopLoading {
LoadTransactionRulesSuccess(this.transactionRules);
final BuiltList<TransactionRuleEntity> transactionRules;
@override
String toString() {
return 'LoadTransactionRulesSuccess{transactionRules: $transactionRules}';
}
}
class SaveTransactionRuleRequest implements StartSaving {
SaveTransactionRuleRequest({this.completer, this.transactionRule});
final Completer completer;
final TransactionRuleEntity transactionRule;
}
class SaveTransactionRuleSuccess implements StopSaving, PersistData, PersistUI {
SaveTransactionRuleSuccess(this.transactionRule);
final TransactionRuleEntity transactionRule;
}
class AddTransactionRuleSuccess implements StopSaving, PersistData, PersistUI {
AddTransactionRuleSuccess(this.transactionRule);
final TransactionRuleEntity transactionRule;
}
class SaveTransactionRuleFailure implements StopSaving {
SaveTransactionRuleFailure(this.error);
final Object error;
}
class ArchiveTransactionRulesRequest implements StartSaving {
ArchiveTransactionRulesRequest(this.completer, this.transactionRuleIds);
final Completer completer;
final List<String> transactionRuleIds;
}
class ArchiveTransactionRulesSuccess implements StopSaving, PersistData {
ArchiveTransactionRulesSuccess(this.transactionRules);
final List<TransactionRuleEntity> transactionRules;
}
class ArchiveTransactionRulesFailure implements StopSaving {
ArchiveTransactionRulesFailure(this.transactionRules);
final List<TransactionRuleEntity> transactionRules;
}
class DeleteTransactionRulesRequest implements StartSaving {
DeleteTransactionRulesRequest(this.completer, this.transactionRuleIds);
final Completer completer;
final List<String> transactionRuleIds;
}
class DeleteTransactionRulesSuccess implements StopSaving, PersistData {
DeleteTransactionRulesSuccess(this.transactionRules);
final List<TransactionRuleEntity> transactionRules;
}
class DeleteTransactionRulesFailure implements StopSaving {
DeleteTransactionRulesFailure(this.transactionRules);
final List<TransactionRuleEntity> transactionRules;
}
class RestoreTransactionRulesRequest implements StartSaving {
RestoreTransactionRulesRequest(this.completer, this.transactionRuleIds);
final Completer completer;
final List<String> transactionRuleIds;
}
class RestoreTransactionRulesSuccess implements StopSaving, PersistData {
RestoreTransactionRulesSuccess(this.transactionRules);
final List<TransactionRuleEntity> transactionRules;
}
class RestoreTransactionRulesFailure implements StopSaving {
RestoreTransactionRulesFailure(this.transactionRules);
final List<TransactionRuleEntity> transactionRules;
}
class FilterTransactionRules implements PersistUI {
FilterTransactionRules(this.filter);
final String filter;
}
class SortTransactionRules implements PersistUI, PersistPrefs {
SortTransactionRules(this.field);
final String field;
}
class FilterTransactionRulesByState implements PersistUI {
FilterTransactionRulesByState(this.state);
final EntityState state;
}
class FilterTransactionRulesByCustom1 implements PersistUI {
FilterTransactionRulesByCustom1(this.value);
final String value;
}
class FilterTransactionRulesByCustom2 implements PersistUI {
FilterTransactionRulesByCustom2(this.value);
final String value;
}
class FilterTransactionRulesByCustom3 implements PersistUI {
FilterTransactionRulesByCustom3(this.value);
final String value;
}
class FilterTransactionRulesByCustom4 implements PersistUI {
FilterTransactionRulesByCustom4(this.value);
final String value;
}
class StartTransactionRuleMultiselect {
StartTransactionRuleMultiselect();
}
class AddToTransactionRuleMultiselect {
AddToTransactionRuleMultiselect({@required this.entity});
final BaseEntity entity;
}
class RemoveFromTransactionRuleMultiselect {
RemoveFromTransactionRuleMultiselect({@required this.entity});
final BaseEntity entity;
}
class ClearTransactionRuleMultiselect {
ClearTransactionRuleMultiselect();
}
class UpdateTransactionRuleTab implements PersistUI {
UpdateTransactionRuleTab({this.tabIndex});
final int tabIndex;
}
void handleTransactionRuleAction(BuildContext context,
List<BaseEntity> transactionRules, EntityAction action) {
if (transactionRules.isEmpty) {
return;
}
final store = StoreProvider.of<AppState>(context);
final localization = AppLocalization.of(context);
final transactionRule = transactionRules.first as TransactionRuleEntity;
final transactionRuleIds =
transactionRules.map((transactionRule) => transactionRule.id).toList();
switch (action) {
case EntityAction.edit:
editEntity(entity: transactionRule);
break;
case EntityAction.restore:
store.dispatch(RestoreTransactionRulesRequest(
snackBarCompleter<Null>(
context, localization.restoredTransactionRule),
transactionRuleIds));
break;
case EntityAction.archive:
store.dispatch(ArchiveTransactionRulesRequest(
snackBarCompleter<Null>(
context, localization.archivedTransactionRule),
transactionRuleIds));
break;
case EntityAction.delete:
store.dispatch(DeleteTransactionRulesRequest(
snackBarCompleter<Null>(context, localization.deletedTransactionRule),
transactionRuleIds));
break;
case EntityAction.toggleMultiselect:
if (!store.state.transactionRuleListState.isInMultiselect()) {
store.dispatch(StartTransactionRuleMultiselect());
}
if (transactionRules.isEmpty) {
break;
}
for (final transactionRule in transactionRules) {
if (!store.state.transactionRuleListState
.isSelected(transactionRule.id)) {
store.dispatch(
AddToTransactionRuleMultiselect(entity: transactionRule));
} else {
store.dispatch(
RemoveFromTransactionRuleMultiselect(entity: transactionRule));
}
}
break;
case EntityAction.more:
showEntityActionsDialog(
entities: [transactionRule],
);
break;
default:
print('## ERROR: unhandled action $action in transaction_rule_actions');
break;
}
}

View File

@ -0,0 +1,247 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:redux/redux.dart';
import 'package:invoiceninja_flutter/main_app.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/ui/ui_actions.dart';
import 'package:invoiceninja_flutter/ui/transaction_rule/transaction_rule_screen.dart';
import 'package:invoiceninja_flutter/ui/transaction_rule/edit/transaction_rule_edit_vm.dart';
import 'package:invoiceninja_flutter/ui/transaction_rule/view/transaction_rule_view_vm.dart';
import 'package:invoiceninja_flutter/redux/transaction_rule/transaction_rule_actions.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/data/repositories/transaction_rule_repository.dart';
List<Middleware<AppState>> createStoreTransactionRulesMiddleware([
TransactionRuleRepository repository = const TransactionRuleRepository(),
]) {
final viewTransactionRuleList = _viewTransactionRuleList();
final viewTransactionRule = _viewTransactionRule();
final editTransactionRule = _editTransactionRule();
final loadTransactionRules = _loadTransactionRules(repository);
final loadTransactionRule = _loadTransactionRule(repository);
final saveTransactionRule = _saveTransactionRule(repository);
final archiveTransactionRule = _archiveTransactionRule(repository);
final deleteTransactionRule = _deleteTransactionRule(repository);
final restoreTransactionRule = _restoreTransactionRule(repository);
return [
TypedMiddleware<AppState, ViewTransactionRuleList>(viewTransactionRuleList),
TypedMiddleware<AppState, ViewTransactionRule>(viewTransactionRule),
TypedMiddleware<AppState, EditTransactionRule>(editTransactionRule),
TypedMiddleware<AppState, LoadTransactionRules>(loadTransactionRules),
TypedMiddleware<AppState, LoadTransactionRule>(loadTransactionRule),
TypedMiddleware<AppState, SaveTransactionRuleRequest>(saveTransactionRule),
TypedMiddleware<AppState, ArchiveTransactionRulesRequest>(
archiveTransactionRule),
TypedMiddleware<AppState, DeleteTransactionRulesRequest>(
deleteTransactionRule),
TypedMiddleware<AppState, RestoreTransactionRulesRequest>(
restoreTransactionRule),
];
}
Middleware<AppState> _editTransactionRule() {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as EditTransactionRule;
next(action);
store.dispatch(UpdateCurrentRoute(TransactionRuleEditScreen.route));
if (store.state.prefState.isMobile) {
navigatorKey.currentState.pushNamed(TransactionRuleEditScreen.route);
}
};
}
Middleware<AppState> _viewTransactionRule() {
return (Store<AppState> store, dynamic dynamicAction,
NextDispatcher next) async {
final action = dynamicAction as ViewTransactionRule;
next(action);
store.dispatch(UpdateCurrentRoute(TransactionRuleViewScreen.route));
if (store.state.prefState.isMobile) {
navigatorKey.currentState.pushNamed(TransactionRuleViewScreen.route);
}
};
}
Middleware<AppState> _viewTransactionRuleList() {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as ViewTransactionRuleList;
next(action);
if (store.state.staticState.isStale) {
store.dispatch(RefreshData());
}
store.dispatch(UpdateCurrentRoute(TransactionRuleScreen.route));
if (store.state.prefState.isMobile) {
navigatorKey.currentState.pushNamedAndRemoveUntil(
TransactionRuleScreen.route, (Route<dynamic> route) => false);
}
};
}
Middleware<AppState> _archiveTransactionRule(
TransactionRuleRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as ArchiveTransactionRulesRequest;
final prevTransactionRules = action.transactionRuleIds
.map((id) => store.state.transactionRuleState.map[id])
.toList();
repository
.bulkAction(store.state.credentials, action.transactionRuleIds,
EntityAction.archive)
.then((List<TransactionRuleEntity> transactionRules) {
store.dispatch(ArchiveTransactionRulesSuccess(transactionRules));
if (action.completer != null) {
action.completer.complete(null);
}
}).catchError((Object error) {
print(error);
store.dispatch(ArchiveTransactionRulesFailure(prevTransactionRules));
if (action.completer != null) {
action.completer.completeError(error);
}
});
next(action);
};
}
Middleware<AppState> _deleteTransactionRule(
TransactionRuleRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as DeleteTransactionRulesRequest;
final prevTransactionRules = action.transactionRuleIds
.map((id) => store.state.transactionRuleState.map[id])
.toList();
repository
.bulkAction(store.state.credentials, action.transactionRuleIds,
EntityAction.delete)
.then((List<TransactionRuleEntity> transactionRules) {
store.dispatch(DeleteTransactionRulesSuccess(transactionRules));
if (action.completer != null) {
action.completer.complete(null);
}
}).catchError((Object error) {
print(error);
store.dispatch(DeleteTransactionRulesFailure(prevTransactionRules));
if (action.completer != null) {
action.completer.completeError(error);
}
});
next(action);
};
}
Middleware<AppState> _restoreTransactionRule(
TransactionRuleRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as RestoreTransactionRulesRequest;
final prevTransactionRules = action.transactionRuleIds
.map((id) => store.state.transactionRuleState.map[id])
.toList();
repository
.bulkAction(store.state.credentials, action.transactionRuleIds,
EntityAction.restore)
.then((List<TransactionRuleEntity> transactionRules) {
store.dispatch(RestoreTransactionRulesSuccess(transactionRules));
if (action.completer != null) {
action.completer.complete(null);
}
}).catchError((Object error) {
print(error);
store.dispatch(RestoreTransactionRulesFailure(prevTransactionRules));
if (action.completer != null) {
action.completer.completeError(error);
}
});
next(action);
};
}
Middleware<AppState> _saveTransactionRule(
TransactionRuleRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as SaveTransactionRuleRequest;
repository
.saveData(store.state.credentials, action.transactionRule)
.then((TransactionRuleEntity transactionRule) {
if (action.transactionRule.isNew) {
store.dispatch(AddTransactionRuleSuccess(transactionRule));
} else {
store.dispatch(SaveTransactionRuleSuccess(transactionRule));
}
action.completer.complete(transactionRule);
}).catchError((Object error) {
print(error);
store.dispatch(SaveTransactionRuleFailure(error));
action.completer.completeError(error);
});
next(action);
};
}
Middleware<AppState> _loadTransactionRule(
TransactionRuleRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as LoadTransactionRule;
final AppState state = store.state;
store.dispatch(LoadTransactionRuleRequest());
repository
.loadItem(state.credentials, action.transactionRuleId)
.then((transactionRule) {
store.dispatch(LoadTransactionRuleSuccess(transactionRule));
if (action.completer != null) {
action.completer.complete(null);
}
}).catchError((Object error) {
print(error);
store.dispatch(LoadTransactionRuleFailure(error));
if (action.completer != null) {
action.completer.completeError(error);
}
});
next(action);
};
}
Middleware<AppState> _loadTransactionRules(
TransactionRuleRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as LoadTransactionRules;
final AppState state = store.state;
store.dispatch(LoadTransactionRulesRequest());
repository.loadList(state.credentials).then((data) {
store.dispatch(LoadTransactionRulesSuccess(data));
if (action.completer != null) {
action.completer.complete(null);
}
}).catchError((Object error) {
print(error);
store.dispatch(LoadTransactionRulesFailure(error));
if (action.completer != null) {
action.completer.completeError(error);
}
});
next(action);
};
}

View File

@ -0,0 +1,296 @@
import 'package:redux/redux.dart';
import 'package:built_collection/built_collection.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/company/company_actions.dart';
import 'package:invoiceninja_flutter/redux/ui/entity_ui_state.dart';
import 'package:invoiceninja_flutter/redux/transaction_rule/transaction_rule_actions.dart';
import 'package:invoiceninja_flutter/redux/ui/list_ui_state.dart';
import 'package:invoiceninja_flutter/redux/transaction_rule/transaction_rule_state.dart';
EntityUIState transactionRuleUIReducer(
TransactionRuleUIState state, dynamic action) {
return state.rebuild((b) => b
..listUIState.replace(transactionRuleListReducer(state.listUIState, action))
..editing.replace(editingReducer(state.editing, action))
..selectedId = selectedIdReducer(state.selectedId, action)
..forceSelected = forceSelectedReducer(state.forceSelected, action)
..tabIndex = tabIndexReducer(state.tabIndex, action));
}
final forceSelectedReducer = combineReducers<bool>([
TypedReducer<bool, ViewTransactionRule>((completer, action) => true),
TypedReducer<bool, ViewTransactionRuleList>((completer, action) => false),
TypedReducer<bool, FilterTransactionRulesByState>(
(completer, action) => false),
TypedReducer<bool, FilterTransactionRules>((completer, action) => false),
TypedReducer<bool, FilterTransactionRulesByCustom1>(
(completer, action) => false),
TypedReducer<bool, FilterTransactionRulesByCustom2>(
(completer, action) => false),
TypedReducer<bool, FilterTransactionRulesByCustom3>(
(completer, action) => false),
TypedReducer<bool, FilterTransactionRulesByCustom4>(
(completer, action) => false),
]);
final tabIndexReducer = combineReducers<int>([
TypedReducer<int, UpdateTransactionRuleTab>((completer, action) {
return action.tabIndex;
}),
TypedReducer<int, PreviewEntity>((completer, action) {
return 0;
}),
]);
Reducer<String> selectedIdReducer = combineReducers([
TypedReducer<String, ArchiveTransactionRulesSuccess>(
(completer, action) => ''),
TypedReducer<String, DeleteTransactionRulesSuccess>(
(completer, action) => ''),
TypedReducer<String, PreviewEntity>((selectedId, action) =>
action.entityType == EntityType.transactionRule
? action.entityId
: selectedId),
TypedReducer<String, ViewTransactionRule>(
(String selectedId, dynamic action) => action.transactionRuleId),
TypedReducer<String, AddTransactionRuleSuccess>(
(String selectedId, dynamic action) => action.transactionRule.id),
TypedReducer<String, SelectCompany>(
(selectedId, action) => action.clearSelection ? '' : selectedId),
TypedReducer<String, ClearEntityFilter>((selectedId, action) => ''),
TypedReducer<String, SortTransactionRules>((selectedId, action) => ''),
TypedReducer<String, FilterTransactionRules>((selectedId, action) => ''),
TypedReducer<String, FilterTransactionRulesByState>(
(selectedId, action) => ''),
TypedReducer<String, FilterTransactionRulesByCustom1>(
(selectedId, action) => ''),
TypedReducer<String, FilterTransactionRulesByCustom2>(
(selectedId, action) => ''),
TypedReducer<String, FilterTransactionRulesByCustom3>(
(selectedId, action) => ''),
TypedReducer<String, FilterTransactionRulesByCustom4>(
(selectedId, action) => ''),
TypedReducer<String, FilterByEntity>(
(selectedId, action) => action.clearSelection
? ''
: action.entityType == EntityType.transactionRule
? action.entityId
: selectedId),
]);
final editingReducer = combineReducers<TransactionRuleEntity>([
TypedReducer<TransactionRuleEntity, SaveTransactionRuleSuccess>(
_updateEditing),
TypedReducer<TransactionRuleEntity, AddTransactionRuleSuccess>(
_updateEditing),
TypedReducer<TransactionRuleEntity, RestoreTransactionRulesSuccess>(
(transactionRules, action) {
return action.transactionRules[0];
}),
TypedReducer<TransactionRuleEntity, ArchiveTransactionRulesSuccess>(
(transactionRules, action) {
return action.transactionRules[0];
}),
TypedReducer<TransactionRuleEntity, DeleteTransactionRulesSuccess>(
(transactionRules, action) {
return action.transactionRules[0];
}),
TypedReducer<TransactionRuleEntity, EditTransactionRule>(_updateEditing),
TypedReducer<TransactionRuleEntity, UpdateTransactionRule>(
(transactionRule, action) {
return action.transactionRule.rebuild((b) => b..isChanged = true);
}),
TypedReducer<TransactionRuleEntity, DiscardChanges>(_clearEditing),
]);
TransactionRuleEntity _clearEditing(
TransactionRuleEntity transactionRule, dynamic action) {
return TransactionRuleEntity();
}
TransactionRuleEntity _updateEditing(
TransactionRuleEntity transactionRule, dynamic action) {
return action.transactionRule;
}
final transactionRuleListReducer = combineReducers<ListUIState>([
TypedReducer<ListUIState, SortTransactionRules>(_sortTransactionRules),
TypedReducer<ListUIState, FilterTransactionRulesByState>(
_filterTransactionRulesByState),
TypedReducer<ListUIState, FilterTransactionRules>(_filterTransactionRules),
TypedReducer<ListUIState, FilterTransactionRulesByCustom1>(
_filterTransactionRulesByCustom1),
TypedReducer<ListUIState, FilterTransactionRulesByCustom2>(
_filterTransactionRulesByCustom2),
TypedReducer<ListUIState, StartTransactionRuleMultiselect>(
_startListMultiselect),
TypedReducer<ListUIState, AddToTransactionRuleMultiselect>(
_addToListMultiselect),
TypedReducer<ListUIState, RemoveFromTransactionRuleMultiselect>(
_removeFromListMultiselect),
TypedReducer<ListUIState, ClearTransactionRuleMultiselect>(
_clearListMultiselect),
TypedReducer<ListUIState, ViewTransactionRuleList>(_viewTransactionRuleList),
]);
ListUIState _viewTransactionRuleList(
ListUIState transactionRuleListState, ViewTransactionRuleList action) {
return transactionRuleListState.rebuild((b) => b
..selectedIds = null
..filter = null
..filterClearedAt = DateTime.now().millisecondsSinceEpoch);
}
ListUIState _filterTransactionRulesByCustom1(
ListUIState transactionRuleListState,
FilterTransactionRulesByCustom1 action) {
if (transactionRuleListState.custom1Filters.contains(action.value)) {
return transactionRuleListState
.rebuild((b) => b..custom1Filters.remove(action.value));
} else {
return transactionRuleListState
.rebuild((b) => b..custom1Filters.add(action.value));
}
}
ListUIState _filterTransactionRulesByCustom2(
ListUIState transactionRuleListState,
FilterTransactionRulesByCustom2 action) {
if (transactionRuleListState.custom2Filters.contains(action.value)) {
return transactionRuleListState
.rebuild((b) => b..custom2Filters.remove(action.value));
} else {
return transactionRuleListState
.rebuild((b) => b..custom2Filters.add(action.value));
}
}
ListUIState _filterTransactionRulesByState(ListUIState transactionRuleListState,
FilterTransactionRulesByState action) {
if (transactionRuleListState.stateFilters.contains(action.state)) {
return transactionRuleListState
.rebuild((b) => b..stateFilters.remove(action.state));
} else {
return transactionRuleListState
.rebuild((b) => b..stateFilters.add(action.state));
}
}
ListUIState _filterTransactionRules(
ListUIState transactionRuleListState, FilterTransactionRules action) {
return transactionRuleListState.rebuild((b) => b
..filter = action.filter
..filterClearedAt = action.filter == null
? DateTime.now().millisecondsSinceEpoch
: transactionRuleListState.filterClearedAt);
}
ListUIState _sortTransactionRules(
ListUIState transactionRuleListState, SortTransactionRules action) {
return transactionRuleListState.rebuild((b) => b
..sortAscending = b.sortField != action.field || !b.sortAscending
..sortField = action.field);
}
ListUIState _startListMultiselect(
ListUIState productListState, StartTransactionRuleMultiselect action) {
return productListState.rebuild((b) => b..selectedIds = ListBuilder());
}
ListUIState _addToListMultiselect(
ListUIState productListState, AddToTransactionRuleMultiselect action) {
return productListState.rebuild((b) => b..selectedIds.add(action.entity.id));
}
ListUIState _removeFromListMultiselect(
ListUIState productListState, RemoveFromTransactionRuleMultiselect action) {
return productListState
.rebuild((b) => b..selectedIds.remove(action.entity.id));
}
ListUIState _clearListMultiselect(
ListUIState productListState, ClearTransactionRuleMultiselect action) {
return productListState.rebuild((b) => b..selectedIds = null);
}
final transactionRulesReducer = combineReducers<TransactionRuleState>([
TypedReducer<TransactionRuleState, SaveTransactionRuleSuccess>(
_updateTransactionRule),
TypedReducer<TransactionRuleState, AddTransactionRuleSuccess>(
_addTransactionRule),
TypedReducer<TransactionRuleState, LoadTransactionRulesSuccess>(
_setLoadedTransactionRules),
TypedReducer<TransactionRuleState, LoadTransactionRuleSuccess>(
_setLoadedTransactionRule),
TypedReducer<TransactionRuleState, LoadCompanySuccess>(_setLoadedCompany),
TypedReducer<TransactionRuleState, ArchiveTransactionRulesSuccess>(
_archiveTransactionRuleSuccess),
TypedReducer<TransactionRuleState, DeleteTransactionRulesSuccess>(
_deleteTransactionRuleSuccess),
TypedReducer<TransactionRuleState, RestoreTransactionRulesSuccess>(
_restoreTransactionRuleSuccess),
]);
TransactionRuleState _archiveTransactionRuleSuccess(
TransactionRuleState transactionRuleState,
ArchiveTransactionRulesSuccess action) {
return transactionRuleState.rebuild((b) {
for (final transactionRule in action.transactionRules) {
b.map[transactionRule.id] = transactionRule;
}
});
}
TransactionRuleState _deleteTransactionRuleSuccess(
TransactionRuleState transactionRuleState,
DeleteTransactionRulesSuccess action) {
return transactionRuleState.rebuild((b) {
for (final transactionRule in action.transactionRules) {
b.map[transactionRule.id] = transactionRule;
}
});
}
TransactionRuleState _restoreTransactionRuleSuccess(
TransactionRuleState transactionRuleState,
RestoreTransactionRulesSuccess action) {
return transactionRuleState.rebuild((b) {
for (final transactionRule in action.transactionRules) {
b.map[transactionRule.id] = transactionRule;
}
});
}
TransactionRuleState _addTransactionRule(
TransactionRuleState transactionRuleState,
AddTransactionRuleSuccess action) {
return transactionRuleState.rebuild((b) => b
..map[action.transactionRule.id] = action.transactionRule
..list.add(action.transactionRule.id));
}
TransactionRuleState _updateTransactionRule(
TransactionRuleState transactionRuleState,
SaveTransactionRuleSuccess action) {
return transactionRuleState.rebuild(
(b) => b..map[action.transactionRule.id] = action.transactionRule);
}
TransactionRuleState _setLoadedTransactionRule(
TransactionRuleState transactionRuleState,
LoadTransactionRuleSuccess action) {
return transactionRuleState.rebuild(
(b) => b..map[action.transactionRule.id] = action.transactionRule);
}
TransactionRuleState _setLoadedTransactionRules(
TransactionRuleState transactionRuleState,
LoadTransactionRulesSuccess action) =>
transactionRuleState.loadTransactionRules(action.transactionRules);
TransactionRuleState _setLoadedCompany(
TransactionRuleState transactionRuleState, LoadCompanySuccess action) {
final company = action.userCompany.company;
return transactionRuleState.loadTransactionRules(company.transactionRules);
}

View File

@ -0,0 +1,98 @@
import 'package:invoiceninja_flutter/redux/static/static_state.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:memoize/memoize.dart';
import 'package:built_collection/built_collection.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/ui/list_ui_state.dart';
var memoizedDropdownTransactionRuleList = memo5(
(BuiltMap<String, TransactionRuleEntity> transactionRuleMap,
BuiltList<String> transactionRuleList,
StaticState staticState,
BuiltMap<String, UserEntity> userMap,
String clientId) =>
dropdownTransactionRulesSelector(transactionRuleMap,
transactionRuleList, staticState, userMap, clientId));
List<String> dropdownTransactionRulesSelector(
BuiltMap<String, TransactionRuleEntity> transactionRuleMap,
BuiltList<String> transactionRuleList,
StaticState staticState,
BuiltMap<String, UserEntity> userMap,
String clientId) {
final list = transactionRuleList.where((transactionRuleId) {
final transactionRule = transactionRuleMap[transactionRuleId];
/*
if (clientId != null && clientId > 0 && transactionRule.clientId != clientId) {
return false;
}
*/
return transactionRule.isActive;
}).toList();
list.sort((transactionRuleAId, transactionRuleBId) {
final transactionRuleA = transactionRuleMap[transactionRuleAId];
final transactionRuleB = transactionRuleMap[transactionRuleBId];
return transactionRuleA.compareTo(
transactionRuleB, TransactionRuleFields.name, true);
});
return list;
}
var memoizedFilteredTransactionRuleList = memo4((SelectionState selectionState,
BuiltMap<String, TransactionRuleEntity> transactionRuleMap,
BuiltList<String> transactionRuleList,
ListUIState transactionRuleListState) =>
filteredTransactionRulesSelector(selectionState, transactionRuleMap,
transactionRuleList, transactionRuleListState));
List<String> filteredTransactionRulesSelector(
SelectionState selectionState,
BuiltMap<String, TransactionRuleEntity> transactionRuleMap,
BuiltList<String> transactionRuleList,
ListUIState transactionRuleListState) {
final filterEntityId = selectionState.filterEntityId;
final filterEntityType = selectionState.filterEntityType;
final list = transactionRuleList.where((transactionRuleId) {
final transactionRule = transactionRuleMap[transactionRuleId];
if (filterEntityId != null && transactionRule.id != filterEntityId) {
return false;
} else {}
if (!transactionRule.matchesStates(transactionRuleListState.stateFilters)) {
return false;
}
if (transactionRuleListState.custom1Filters.isNotEmpty &&
!transactionRuleListState.custom1Filters
.contains(transactionRule.customValue1)) {
return false;
} else if (transactionRuleListState.custom2Filters.isNotEmpty &&
!transactionRuleListState.custom2Filters
.contains(transactionRule.customValue2)) {
return false;
} else if (transactionRuleListState.custom3Filters.isNotEmpty &&
!transactionRuleListState.custom3Filters
.contains(transactionRule.customValue3)) {
return false;
} else if (transactionRuleListState.custom4Filters.isNotEmpty &&
!transactionRuleListState.custom4Filters
.contains(transactionRule.customValue4)) {
return false;
}
return transactionRule.matchesFilter(transactionRuleListState.filter);
}).toList();
list.sort((transactionRuleAId, transactionRuleBId) {
final transactionRuleA = transactionRuleMap[transactionRuleAId];
final transactionRuleB = transactionRuleMap[transactionRuleBId];
return transactionRuleA.compareTo(
transactionRuleB,
transactionRuleListState.sortField,
transactionRuleListState.sortAscending);
});
return list;
}

View File

@ -0,0 +1,83 @@
import 'dart:async';
import 'package:built_value/built_value.dart';
import 'package:built_value/serializer.dart';
import 'package:built_collection/built_collection.dart';
import 'package:invoiceninja_flutter/redux/ui/entity_ui_state.dart';
import 'package:invoiceninja_flutter/redux/ui/list_ui_state.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/ui/pref_state.dart';
part 'transaction_rule_state.g.dart';
abstract class TransactionRuleState
implements Built<TransactionRuleState, TransactionRuleStateBuilder> {
factory TransactionRuleState() {
return _$TransactionRuleState._(
map: BuiltMap<String, TransactionRuleEntity>(),
list: BuiltList<String>(),
);
}
TransactionRuleState._();
@override
@memoized
int get hashCode;
BuiltMap<String, TransactionRuleEntity> get map;
BuiltList<String> get list;
TransactionRuleEntity get(String transactionRuleId) {
if (map.containsKey(transactionRuleId)) {
return map[transactionRuleId];
} else {
return TransactionRuleEntity(id: transactionRuleId);
}
}
TransactionRuleState loadTransactionRules(
BuiltList<TransactionRuleEntity> clients) {
final map = Map<String, TransactionRuleEntity>.fromIterable(
clients,
key: (dynamic item) => item.id,
value: (dynamic item) => item,
);
return rebuild((b) => b
..map.addAll(map)
..list.replace((map.keys.toList() + list.toList()).toSet().toList()));
}
static Serializer<TransactionRuleState> get serializer =>
_$transactionRuleStateSerializer;
}
abstract class TransactionRuleUIState extends Object
with EntityUIState
implements Built<TransactionRuleUIState, TransactionRuleUIStateBuilder> {
factory TransactionRuleUIState(PrefStateSortField sortField) {
return _$TransactionRuleUIState._(
listUIState: ListUIState(sortField?.field ?? TransactionRuleFields.name,
sortAscending: sortField?.ascending),
editing: TransactionRuleEntity(),
selectedId: '',
tabIndex: 0,
);
}
TransactionRuleUIState._();
@override
@memoized
int get hashCode;
@nullable
TransactionRuleEntity get editing;
@override
bool get isCreatingNew => editing.isNew;
@override
String get editingId => editing.id;
static Serializer<TransactionRuleUIState> get serializer =>
_$transactionRuleUIStateSerializer;
}

View File

@ -0,0 +1,455 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'transaction_rule_state.dart';
// **************************************************************************
// BuiltValueGenerator
// **************************************************************************
Serializer<TransactionRuleState> _$transactionRuleStateSerializer =
new _$TransactionRuleStateSerializer();
Serializer<TransactionRuleUIState> _$transactionRuleUIStateSerializer =
new _$TransactionRuleUIStateSerializer();
class _$TransactionRuleStateSerializer
implements StructuredSerializer<TransactionRuleState> {
@override
final Iterable<Type> types = const [
TransactionRuleState,
_$TransactionRuleState
];
@override
final String wireName = 'TransactionRuleState';
@override
Iterable<Object> serialize(
Serializers serializers, TransactionRuleState object,
{FullType specifiedType = FullType.unspecified}) {
final result = <Object>[
'map',
serializers.serialize(object.map,
specifiedType: const FullType(BuiltMap, const [
const FullType(String),
const FullType(TransactionRuleEntity)
])),
'list',
serializers.serialize(object.list,
specifiedType:
const FullType(BuiltList, const [const FullType(String)])),
];
return result;
}
@override
TransactionRuleState deserialize(
Serializers serializers, Iterable<Object> serialized,
{FullType specifiedType = FullType.unspecified}) {
final result = new TransactionRuleStateBuilder();
final iterator = serialized.iterator;
while (iterator.moveNext()) {
final key = iterator.current as String;
iterator.moveNext();
final Object value = iterator.current;
switch (key) {
case 'map':
result.map.replace(serializers.deserialize(value,
specifiedType: const FullType(BuiltMap, const [
const FullType(String),
const FullType(TransactionRuleEntity)
])));
break;
case 'list':
result.list.replace(serializers.deserialize(value,
specifiedType:
const FullType(BuiltList, const [const FullType(String)]))
as BuiltList<Object>);
break;
}
}
return result.build();
}
}
class _$TransactionRuleUIStateSerializer
implements StructuredSerializer<TransactionRuleUIState> {
@override
final Iterable<Type> types = const [
TransactionRuleUIState,
_$TransactionRuleUIState
];
@override
final String wireName = 'TransactionRuleUIState';
@override
Iterable<Object> serialize(
Serializers serializers, TransactionRuleUIState object,
{FullType specifiedType = FullType.unspecified}) {
final result = <Object>[
'listUIState',
serializers.serialize(object.listUIState,
specifiedType: const FullType(ListUIState)),
'tabIndex',
serializers.serialize(object.tabIndex,
specifiedType: const FullType(int)),
];
Object value;
value = object.editing;
if (value != null) {
result
..add('editing')
..add(serializers.serialize(value,
specifiedType: const FullType(TransactionRuleEntity)));
}
value = object.selectedId;
if (value != null) {
result
..add('selectedId')
..add(serializers.serialize(value,
specifiedType: const FullType(String)));
}
value = object.forceSelected;
if (value != null) {
result
..add('forceSelected')
..add(
serializers.serialize(value, specifiedType: const FullType(bool)));
}
return result;
}
@override
TransactionRuleUIState deserialize(
Serializers serializers, Iterable<Object> serialized,
{FullType specifiedType = FullType.unspecified}) {
final result = new TransactionRuleUIStateBuilder();
final iterator = serialized.iterator;
while (iterator.moveNext()) {
final key = iterator.current as String;
iterator.moveNext();
final Object value = iterator.current;
switch (key) {
case 'editing':
result.editing.replace(serializers.deserialize(value,
specifiedType: const FullType(TransactionRuleEntity))
as TransactionRuleEntity);
break;
case 'listUIState':
result.listUIState.replace(serializers.deserialize(value,
specifiedType: const FullType(ListUIState)) as ListUIState);
break;
case 'selectedId':
result.selectedId = serializers.deserialize(value,
specifiedType: const FullType(String)) as String;
break;
case 'forceSelected':
result.forceSelected = serializers.deserialize(value,
specifiedType: const FullType(bool)) as bool;
break;
case 'tabIndex':
result.tabIndex = serializers.deserialize(value,
specifiedType: const FullType(int)) as int;
break;
}
}
return result.build();
}
}
class _$TransactionRuleState extends TransactionRuleState {
@override
final BuiltMap<String, TransactionRuleEntity> map;
@override
final BuiltList<String> list;
factory _$TransactionRuleState(
[void Function(TransactionRuleStateBuilder) updates]) =>
(new TransactionRuleStateBuilder()..update(updates)).build();
_$TransactionRuleState._({this.map, this.list}) : super._() {
BuiltValueNullFieldError.checkNotNull(map, 'TransactionRuleState', 'map');
BuiltValueNullFieldError.checkNotNull(list, 'TransactionRuleState', 'list');
}
@override
TransactionRuleState rebuild(
void Function(TransactionRuleStateBuilder) updates) =>
(toBuilder()..update(updates)).build();
@override
TransactionRuleStateBuilder toBuilder() =>
new TransactionRuleStateBuilder()..replace(this);
@override
bool operator ==(Object other) {
if (identical(other, this)) return true;
return other is TransactionRuleState &&
map == other.map &&
list == other.list;
}
int __hashCode;
@override
int get hashCode {
return __hashCode ??= $jf($jc($jc(0, map.hashCode), list.hashCode));
}
@override
String toString() {
return (newBuiltValueToStringHelper('TransactionRuleState')
..add('map', map)
..add('list', list))
.toString();
}
}
class TransactionRuleStateBuilder
implements Builder<TransactionRuleState, TransactionRuleStateBuilder> {
_$TransactionRuleState _$v;
MapBuilder<String, TransactionRuleEntity> _map;
MapBuilder<String, TransactionRuleEntity> get map =>
_$this._map ??= new MapBuilder<String, TransactionRuleEntity>();
set map(MapBuilder<String, TransactionRuleEntity> map) => _$this._map = map;
ListBuilder<String> _list;
ListBuilder<String> get list => _$this._list ??= new ListBuilder<String>();
set list(ListBuilder<String> list) => _$this._list = list;
TransactionRuleStateBuilder();
TransactionRuleStateBuilder get _$this {
final $v = _$v;
if ($v != null) {
_map = $v.map.toBuilder();
_list = $v.list.toBuilder();
_$v = null;
}
return this;
}
@override
void replace(TransactionRuleState other) {
ArgumentError.checkNotNull(other, 'other');
_$v = other as _$TransactionRuleState;
}
@override
void update(void Function(TransactionRuleStateBuilder) updates) {
if (updates != null) updates(this);
}
@override
_$TransactionRuleState build() {
_$TransactionRuleState _$result;
try {
_$result = _$v ??
new _$TransactionRuleState._(map: map.build(), list: list.build());
} catch (_) {
String _$failedField;
try {
_$failedField = 'map';
map.build();
_$failedField = 'list';
list.build();
} catch (e) {
throw new BuiltValueNestedFieldError(
'TransactionRuleState', _$failedField, e.toString());
}
rethrow;
}
replace(_$result);
return _$result;
}
}
class _$TransactionRuleUIState extends TransactionRuleUIState {
@override
final TransactionRuleEntity editing;
@override
final ListUIState listUIState;
@override
final String selectedId;
@override
final bool forceSelected;
@override
final int tabIndex;
@override
final Completer<SelectableEntity> saveCompleter;
@override
final Completer<Null> cancelCompleter;
factory _$TransactionRuleUIState(
[void Function(TransactionRuleUIStateBuilder) updates]) =>
(new TransactionRuleUIStateBuilder()..update(updates)).build();
_$TransactionRuleUIState._(
{this.editing,
this.listUIState,
this.selectedId,
this.forceSelected,
this.tabIndex,
this.saveCompleter,
this.cancelCompleter})
: super._() {
BuiltValueNullFieldError.checkNotNull(
listUIState, 'TransactionRuleUIState', 'listUIState');
BuiltValueNullFieldError.checkNotNull(
tabIndex, 'TransactionRuleUIState', 'tabIndex');
}
@override
TransactionRuleUIState rebuild(
void Function(TransactionRuleUIStateBuilder) updates) =>
(toBuilder()..update(updates)).build();
@override
TransactionRuleUIStateBuilder toBuilder() =>
new TransactionRuleUIStateBuilder()..replace(this);
@override
bool operator ==(Object other) {
if (identical(other, this)) return true;
return other is TransactionRuleUIState &&
editing == other.editing &&
listUIState == other.listUIState &&
selectedId == other.selectedId &&
forceSelected == other.forceSelected &&
tabIndex == other.tabIndex &&
saveCompleter == other.saveCompleter &&
cancelCompleter == other.cancelCompleter;
}
int __hashCode;
@override
int get hashCode {
return __hashCode ??= $jf($jc(
$jc(
$jc(
$jc(
$jc($jc($jc(0, editing.hashCode), listUIState.hashCode),
selectedId.hashCode),
forceSelected.hashCode),
tabIndex.hashCode),
saveCompleter.hashCode),
cancelCompleter.hashCode));
}
@override
String toString() {
return (newBuiltValueToStringHelper('TransactionRuleUIState')
..add('editing', editing)
..add('listUIState', listUIState)
..add('selectedId', selectedId)
..add('forceSelected', forceSelected)
..add('tabIndex', tabIndex)
..add('saveCompleter', saveCompleter)
..add('cancelCompleter', cancelCompleter))
.toString();
}
}
class TransactionRuleUIStateBuilder
implements Builder<TransactionRuleUIState, TransactionRuleUIStateBuilder> {
_$TransactionRuleUIState _$v;
TransactionRuleEntityBuilder _editing;
TransactionRuleEntityBuilder get editing =>
_$this._editing ??= new TransactionRuleEntityBuilder();
set editing(TransactionRuleEntityBuilder editing) =>
_$this._editing = editing;
ListUIStateBuilder _listUIState;
ListUIStateBuilder get listUIState =>
_$this._listUIState ??= new ListUIStateBuilder();
set listUIState(ListUIStateBuilder listUIState) =>
_$this._listUIState = listUIState;
String _selectedId;
String get selectedId => _$this._selectedId;
set selectedId(String selectedId) => _$this._selectedId = selectedId;
bool _forceSelected;
bool get forceSelected => _$this._forceSelected;
set forceSelected(bool forceSelected) =>
_$this._forceSelected = forceSelected;
int _tabIndex;
int get tabIndex => _$this._tabIndex;
set tabIndex(int tabIndex) => _$this._tabIndex = tabIndex;
Completer<SelectableEntity> _saveCompleter;
Completer<SelectableEntity> get saveCompleter => _$this._saveCompleter;
set saveCompleter(Completer<SelectableEntity> saveCompleter) =>
_$this._saveCompleter = saveCompleter;
Completer<Null> _cancelCompleter;
Completer<Null> get cancelCompleter => _$this._cancelCompleter;
set cancelCompleter(Completer<Null> cancelCompleter) =>
_$this._cancelCompleter = cancelCompleter;
TransactionRuleUIStateBuilder();
TransactionRuleUIStateBuilder get _$this {
final $v = _$v;
if ($v != null) {
_editing = $v.editing?.toBuilder();
_listUIState = $v.listUIState.toBuilder();
_selectedId = $v.selectedId;
_forceSelected = $v.forceSelected;
_tabIndex = $v.tabIndex;
_saveCompleter = $v.saveCompleter;
_cancelCompleter = $v.cancelCompleter;
_$v = null;
}
return this;
}
@override
void replace(TransactionRuleUIState other) {
ArgumentError.checkNotNull(other, 'other');
_$v = other as _$TransactionRuleUIState;
}
@override
void update(void Function(TransactionRuleUIStateBuilder) updates) {
if (updates != null) updates(this);
}
@override
_$TransactionRuleUIState build() {
_$TransactionRuleUIState _$result;
try {
_$result = _$v ??
new _$TransactionRuleUIState._(
editing: _editing?.build(),
listUIState: listUIState.build(),
selectedId: selectedId,
forceSelected: forceSelected,
tabIndex: BuiltValueNullFieldError.checkNotNull(
tabIndex, 'TransactionRuleUIState', 'tabIndex'),
saveCompleter: saveCompleter,
cancelCompleter: cancelCompleter);
} catch (_) {
String _$failedField;
try {
_$failedField = 'editing';
_editing?.build();
_$failedField = 'listUIState';
listUIState.build();
} catch (e) {
throw new BuiltValueNestedFieldError(
'TransactionRuleUIState', _$failedField, e.toString());
}
rethrow;
}
replace(_$result);
return _$result;
}
}
// ignore_for_file: always_put_control_body_on_new_line,always_specify_types,annotate_overrides,avoid_annotating_with_dynamic,avoid_as,avoid_catches_without_on_clauses,avoid_returning_this,deprecated_member_use_from_same_package,lines_longer_than_80_chars,omit_local_variable_types,prefer_expression_function_bodies,sort_constructors_first,test_types_in_equals,unnecessary_const,unnecessary_new

View File

@ -40,6 +40,8 @@ import 'package:invoiceninja_flutter/redux/vendor/vendor_actions.dart';
import 'package:invoiceninja_flutter/redux/webhook/webhook_actions.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/redux/transaction_rule/transaction_rule_actions.dart';
import 'package:invoiceninja_flutter/redux/transaction/transaction_actions.dart';
import 'package:invoiceninja_flutter/redux/bank_account/bank_account_actions.dart';
@ -575,6 +577,19 @@ Reducer<BuiltList<HistoryRecord>> historyReducer = combineReducers([
_addToHistory(historyList,
HistoryRecord(id: action.group.id, entityType: EntityType.group))),
// STARTER: history - do not remove comment
TypedReducer<BuiltList<HistoryRecord>, ViewTransactionRule>(
(historyList, action) => _addToHistory(
historyList,
HistoryRecord(
id: action.transactionRuleId,
entityType: EntityType.transactionRule))),
TypedReducer<BuiltList<HistoryRecord>, EditTransactionRule>(
(historyList, action) => _addToHistory(
historyList,
HistoryRecord(
id: action.transactionRule.id,
entityType: EntityType.transactionRule))),
TypedReducer<BuiltList<HistoryRecord>, ViewTransaction>(
(historyList, action) => _addToHistory(
historyList,

View File

@ -52,6 +52,8 @@ import 'package:invoiceninja_flutter/redux/vendor/vendor_reducer.dart';
import 'package:invoiceninja_flutter/redux/webhook/webhook_reducer.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/redux/transaction_rule/transaction_rule_reducer.dart';
import 'package:invoiceninja_flutter/redux/transaction/transaction_reducer.dart';
import 'package:invoiceninja_flutter/redux/bank_account/bank_account_reducer.dart';
@ -83,6 +85,8 @@ UIState uiReducer(UIState state, dynamic action) {
.replace(dashboardUIReducer(state.dashboardUIState, action))
..reportsUIState.replace(reportsUIReducer(state.reportsUIState, action))
// STARTER: reducer - do not remove comment
..transactionRuleUIState
.replace(transactionRuleUIReducer(state.transactionRuleUIState, action))
..transactionUIState
.replace(transactionUIReducer(state.transactionUIState, action))
..bankAccountUIState

View File

@ -38,6 +38,8 @@ import 'package:invoiceninja_flutter/ui/auth/login_vm.dart';
import 'package:invoiceninja_flutter/utils/strings.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/redux/transaction_rule/transaction_rule_state.dart';
import 'package:invoiceninja_flutter/redux/transaction/transaction_state.dart';
import 'package:invoiceninja_flutter/redux/bank_account/bank_account_state.dart';
@ -91,6 +93,9 @@ abstract class UIState implements Built<UIState, UIStateBuilder> {
paymentUIState: PaymentUIState(sortFields[EntityType.payment]),
quoteUIState: QuoteUIState(sortFields[EntityType.quote]),
// STARTER: constructor - do not remove comment
transactionRuleUIState:
TransactionRuleUIState(sortFields[EntityType.transactionRule]),
transactionUIState:
TransactionUIState(sortFields[EntityType.transaction]),
@ -147,6 +152,8 @@ abstract class UIState implements Built<UIState, UIStateBuilder> {
InvoiceUIState get invoiceUIState;
// STARTER: properties - do not remove comment
TransactionRuleUIState get transactionRuleUIState;
TransactionUIState get transactionUIState;
BankAccountUIState get bankAccountUIState;

View File

@ -53,6 +53,9 @@ class _$UIStateSerializer implements StructuredSerializer<UIState> {
'invoiceUIState',
serializers.serialize(object.invoiceUIState,
specifiedType: const FullType(InvoiceUIState)),
'transactionRuleUIState',
serializers.serialize(object.transactionRuleUIState,
specifiedType: const FullType(TransactionRuleUIState)),
'transactionUIState',
serializers.serialize(object.transactionUIState,
specifiedType: const FullType(TransactionUIState)),
@ -218,6 +221,11 @@ class _$UIStateSerializer implements StructuredSerializer<UIState> {
result.invoiceUIState.replace(serializers.deserialize(value,
specifiedType: const FullType(InvoiceUIState)) as InvoiceUIState);
break;
case 'transactionRuleUIState':
result.transactionRuleUIState.replace(serializers.deserialize(value,
specifiedType: const FullType(TransactionRuleUIState))
as TransactionRuleUIState);
break;
case 'transactionUIState':
result.transactionUIState.replace(serializers.deserialize(value,
specifiedType: const FullType(TransactionUIState))
@ -369,6 +377,8 @@ class _$UIState extends UIState {
@override
final InvoiceUIState invoiceUIState;
@override
final TransactionRuleUIState transactionRuleUIState;
@override
final TransactionUIState transactionUIState;
@override
final BankAccountUIState bankAccountUIState;
@ -438,6 +448,7 @@ class _$UIState extends UIState {
this.productUIState,
this.clientUIState,
this.invoiceUIState,
this.transactionRuleUIState,
this.transactionUIState,
this.bankAccountUIState,
this.purchaseOrderUIState,
@ -487,6 +498,8 @@ class _$UIState extends UIState {
clientUIState, 'UIState', 'clientUIState');
BuiltValueNullFieldError.checkNotNull(
invoiceUIState, 'UIState', 'invoiceUIState');
BuiltValueNullFieldError.checkNotNull(
transactionRuleUIState, 'UIState', 'transactionRuleUIState');
BuiltValueNullFieldError.checkNotNull(
transactionUIState, 'UIState', 'transactionUIState');
BuiltValueNullFieldError.checkNotNull(
@ -565,6 +578,7 @@ class _$UIState extends UIState {
productUIState == other.productUIState &&
clientUIState == other.clientUIState &&
invoiceUIState == other.invoiceUIState &&
transactionRuleUIState == other.transactionRuleUIState &&
transactionUIState == other.transactionUIState &&
bankAccountUIState == other.bankAccountUIState &&
purchaseOrderUIState == other.purchaseOrderUIState &&
@ -614,7 +628,7 @@ class _$UIState extends UIState {
$jc(
$jc(
$jc(
$jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc(0, selectedCompanyIndex.hashCode), currentRoute.hashCode), previousRoute.hashCode), loadingEntityType.hashCode), previewStack.hashCode), filterStack.hashCode), filter.hashCode), filterClearedAt.hashCode), lastActivityAt.hashCode), dashboardUIState.hashCode), productUIState.hashCode), clientUIState.hashCode), invoiceUIState.hashCode), transactionUIState.hashCode), bankAccountUIState.hashCode), purchaseOrderUIState.hashCode), recurringExpenseUIState.hashCode), subscriptionUIState.hashCode), taskStatusUIState.hashCode), expenseCategoryUIState.hashCode),
$jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc(0, selectedCompanyIndex.hashCode), currentRoute.hashCode), previousRoute.hashCode), loadingEntityType.hashCode), previewStack.hashCode), filterStack.hashCode), filter.hashCode), filterClearedAt.hashCode), lastActivityAt.hashCode), dashboardUIState.hashCode), productUIState.hashCode), clientUIState.hashCode), invoiceUIState.hashCode), transactionRuleUIState.hashCode), transactionUIState.hashCode), bankAccountUIState.hashCode), purchaseOrderUIState.hashCode), recurringExpenseUIState.hashCode), subscriptionUIState.hashCode), taskStatusUIState.hashCode), expenseCategoryUIState.hashCode),
recurringInvoiceUIState.hashCode),
webhookUIState.hashCode),
tokenUIState.hashCode),
@ -652,6 +666,7 @@ class _$UIState extends UIState {
..add('productUIState', productUIState)
..add('clientUIState', clientUIState)
..add('invoiceUIState', invoiceUIState)
..add('transactionRuleUIState', transactionRuleUIState)
..add('transactionUIState', transactionUIState)
..add('bankAccountUIState', bankAccountUIState)
..add('purchaseOrderUIState', purchaseOrderUIState)
@ -754,6 +769,13 @@ class UIStateBuilder implements Builder<UIState, UIStateBuilder> {
set invoiceUIState(InvoiceUIStateBuilder invoiceUIState) =>
_$this._invoiceUIState = invoiceUIState;
TransactionRuleUIStateBuilder _transactionRuleUIState;
TransactionRuleUIStateBuilder get transactionRuleUIState =>
_$this._transactionRuleUIState ??= new TransactionRuleUIStateBuilder();
set transactionRuleUIState(
TransactionRuleUIStateBuilder transactionRuleUIState) =>
_$this._transactionRuleUIState = transactionRuleUIState;
TransactionUIStateBuilder _transactionUIState;
TransactionUIStateBuilder get transactionUIState =>
_$this._transactionUIState ??= new TransactionUIStateBuilder();
@ -934,6 +956,7 @@ class UIStateBuilder implements Builder<UIState, UIStateBuilder> {
_productUIState = $v.productUIState.toBuilder();
_clientUIState = $v.clientUIState.toBuilder();
_invoiceUIState = $v.invoiceUIState.toBuilder();
_transactionRuleUIState = $v.transactionRuleUIState.toBuilder();
_transactionUIState = $v.transactionUIState.toBuilder();
_bankAccountUIState = $v.bankAccountUIState.toBuilder();
_purchaseOrderUIState = $v.purchaseOrderUIState.toBuilder();
@ -1000,6 +1023,7 @@ class UIStateBuilder implements Builder<UIState, UIStateBuilder> {
productUIState: productUIState.build(),
clientUIState: clientUIState.build(),
invoiceUIState: invoiceUIState.build(),
transactionRuleUIState: transactionRuleUIState.build(),
transactionUIState: transactionUIState.build(),
bankAccountUIState: bankAccountUIState.build(),
purchaseOrderUIState: purchaseOrderUIState.build(),
@ -1042,6 +1066,8 @@ class UIStateBuilder implements Builder<UIState, UIStateBuilder> {
clientUIState.build();
_$failedField = 'invoiceUIState';
invoiceUIState.build();
_$failedField = 'transactionRuleUIState';
transactionRuleUIState.build();
_$failedField = 'transactionUIState';
transactionUIState.build();
_$failedField = 'bankAccountUIState';

View File

@ -648,6 +648,13 @@ class _MenuDrawerState extends State<MenuDrawer> {
iconTooltip: localization.newExpense,
),
// STARTER: menu - do not remove comment
DrawerTile(
company: company,
entityType: EntityType.transactionRule,
icon: getEntityIcon(EntityType.transactionRule),
title: localization.transactionRules,
),
DrawerTile(
company: company,
entityType: EntityType.recurringExpense,

View File

@ -0,0 +1,112 @@
import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/ui/app/edit_scaffold.dart';
import 'package:invoiceninja_flutter/ui/app/form_card.dart';
import 'package:invoiceninja_flutter/ui/transaction_rule/edit/transaction_rule_edit_vm.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/ui/app/scrollable_listview.dart';
class TransactionRuleEdit extends StatefulWidget {
const TransactionRuleEdit({
Key key,
@required this.viewModel,
}) : super(key: key);
final TransactionRuleEditVM viewModel;
@override
_TransactionRuleEditState createState() => _TransactionRuleEditState();
}
class _TransactionRuleEditState extends State<TransactionRuleEdit> {
static final GlobalKey<FormState> _formKey =
GlobalKey<FormState>(debugLabel: '_transactionRuleEdit');
final _debouncer = Debouncer();
// STARTER: controllers - do not remove comment
final _transaction_rulesController = TextEditingController();
List<TextEditingController> _controllers = [];
@override
void didChangeDependencies() {
_controllers = [
// STARTER: array - do not remove comment
_transaction_rulesController,
];
_controllers.forEach((controller) => controller.removeListener(_onChanged));
final transactionRule = widget.viewModel.transactionRule;
// STARTER: read value - do not remove comment
_transaction_rulesController.text = transaction_rule.transaction_rules;
_controllers.forEach((controller) => controller.addListener(_onChanged));
super.didChangeDependencies();
}
@override
void dispose() {
_controllers.forEach((controller) {
controller.removeListener(_onChanged);
controller.dispose();
});
super.dispose();
}
void _onChanged() {
_debouncer.run(() {
final transactionRule = widget.viewModel.transactionRule.rebuild((b) => b
// STARTER: set value - do not remove comment
..transaction_rules = _transaction_rulesController.text.trim());
if (transactionRule != widget.viewModel.transactionRule) {
widget.viewModel.onChanged(transactionRule);
}
});
}
@override
Widget build(BuildContext context) {
final viewModel = widget.viewModel;
final localization = AppLocalization.of(context);
final transactionRule = viewModel.transactionRule;
return EditScaffold(
title: transactionRule.isNew
? localization.newTransactionRule
: localization.editTransactionRule,
onCancelPressed: (context) => viewModel.onCancelPressed(context),
onSavePressed: (context) {
final bool isValid = _formKey.currentState.validate();
if (!isValid) {
return;
}
viewModel.onSavePressed(context);
},
body: Form(
key: _formKey,
child: Builder(builder: (BuildContext context) {
return ScrollableListView(
children: <Widget>[
FormCard(
children: <Widget>[
// STARTER: widgets - do not remove comment
TextFormField(
controller: _transaction_rulesController,
autocorrect: false,
decoration: InputDecoration(
labelText: 'Transaction_rules',
),
),
],
),
],
);
})),
);
}
}

View File

@ -0,0 +1,118 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:invoiceninja_flutter/redux/ui/ui_actions.dart';
import 'package:redux/redux.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/ui/app/dialogs/error_dialog.dart';
import 'package:invoiceninja_flutter/ui/transaction_rule/view/transaction_rule_view_vm.dart';
import 'package:invoiceninja_flutter/redux/transaction_rule/transaction_rule_actions.dart';
import 'package:invoiceninja_flutter/ui/transaction_rule/edit/transaction_rule_edit.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:flutter_styled_toast/flutter_styled_toast.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
class TransactionRuleEditScreen extends StatelessWidget {
const TransactionRuleEditScreen({Key key}) : super(key: key);
static const String route = '/transaction_rule/edit';
@override
Widget build(BuildContext context) {
return StoreConnector<AppState, TransactionRuleEditVM>(
converter: (Store<AppState> store) {
return TransactionRuleEditVM.fromStore(store);
},
builder: (context, viewModel) {
return TransactionRuleEdit(
viewModel: viewModel,
key: ValueKey(viewModel.transactionRule.updatedAt),
);
},
);
}
}
class TransactionRuleEditVM {
TransactionRuleEditVM({
@required this.state,
@required this.transactionRule,
@required this.company,
@required this.onChanged,
@required this.isSaving,
@required this.origTransactionRule,
@required this.onSavePressed,
@required this.onCancelPressed,
@required this.isLoading,
});
factory TransactionRuleEditVM.fromStore(Store<AppState> store) {
final state = store.state;
final transactionRule = state.transactionRuleUIState.editing;
return TransactionRuleEditVM(
state: state,
isLoading: state.isLoading,
isSaving: state.isSaving,
origTransactionRule: state.transactionRuleState.map[transactionRule.id],
transactionRule: transactionRule,
company: state.company,
onChanged: (TransactionRuleEntity transactionRule) {
store.dispatch(UpdateTransactionRule(transactionRule));
},
onCancelPressed: (BuildContext context) {
createEntity(
context: context, entity: TransactionRuleEntity(), force: true);
if (state.transactionRuleUIState.cancelCompleter != null) {
state.transactionRuleUIState.cancelCompleter.complete();
} else {
store.dispatch(UpdateCurrentRoute(state.uiState.previousRoute));
}
},
onSavePressed: (BuildContext context) {
Debouncer.runOnComplete(() {
final transactionRule = store.state.transactionRuleUIState.editing;
final localization = AppLocalization.of(context);
final Completer<TransactionRuleEntity> completer =
new Completer<TransactionRuleEntity>();
store.dispatch(SaveTransactionRuleRequest(
completer: completer, transactionRule: transactionRule));
return completer.future.then((savedTransactionRule) {
showToast(transactionRule.isNew
? localization.createdTransactionRule
: localization.updatedTransactionRule);
if (state.prefState.isMobile) {
store.dispatch(
UpdateCurrentRoute(TransactionRuleViewScreen.route));
if (transactionRule.isNew) {
Navigator.of(context)
.pushReplacementNamed(TransactionRuleViewScreen.route);
} else {
Navigator.of(context).pop(savedTransactionRule);
}
} else {
viewEntity(entity: savedTransactionRule, force: true);
}
}).catchError((Object error) {
showDialog<ErrorDialog>(
context: context,
builder: (BuildContext context) {
return ErrorDialog(error);
});
});
});
},
);
}
final TransactionRuleEntity transactionRule;
final CompanyEntity company;
final Function(TransactionRuleEntity) onChanged;
final Function(BuildContext) onSavePressed;
final Function(BuildContext) onCancelPressed;
final bool isLoading;
final bool isSaving;
final TransactionRuleEntity origTransactionRule;
final AppState state;
}

View File

@ -0,0 +1,99 @@
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/ui/app/entity_state_label.dart';
import 'package:invoiceninja_flutter/utils/formatting.dart';
import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/ui/app/dismissible_entity.dart';
class TransactionRuleListItem extends StatelessWidget {
const TransactionRuleListItem({
@required this.user,
@required this.transactionRule,
@required this.filter,
this.onTap,
this.onLongPress,
this.onCheckboxChanged,
this.isChecked = false,
});
final UserEntity user;
final GestureTapCallback onTap;
final GestureTapCallback onLongPress;
final TransactionRuleEntity transactionRule;
final String filter;
final Function(bool) onCheckboxChanged;
final bool isChecked;
@override
Widget build(BuildContext context) {
final store = StoreProvider.of<AppState>(context);
final state = store.state;
final uiState = state.uiState;
final transactionRuleUIState = uiState.transactionRuleUIState;
final listUIState = transactionRuleUIState.listUIState;
final isInMultiselect = listUIState.isInMultiselect();
final showCheckbox = onCheckboxChanged != null || isInMultiselect;
final filterMatch = filter != null && filter.isNotEmpty
? transactionRule.matchesFilterValue(filter)
: null;
final subtitle = filterMatch;
return DismissibleEntity(
userCompany: state.userCompany,
entity: transactionRule,
isSelected: transactionRule.id ==
(uiState.isEditing
? transactionRuleUIState.editing.id
: transactionRuleUIState.selectedId),
child: ListTile(
onTap: () =>
onTap != null ? onTap() : selectEntity(entity: transactionRule),
onLongPress: () => onLongPress != null
? onLongPress()
: selectEntity(entity: transactionRule, longPress: true),
leading: showCheckbox
? IgnorePointer(
ignoring: listUIState.isInMultiselect(),
child: Checkbox(
value: isChecked,
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
onChanged: (value) => onCheckboxChanged(value),
activeColor: Theme.of(context).colorScheme.secondary,
),
)
: null,
title: Container(
width: MediaQuery.of(context).size.width,
child: Row(
children: <Widget>[
Expanded(
child: Text(
transactionRule.name,
style: Theme.of(context).textTheme.subtitle1,
),
),
Text(formatNumber(transactionRule.listDisplayAmount, context),
style: Theme.of(context).textTheme.subtitle1),
],
),
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
subtitle != null && subtitle.isNotEmpty
? Text(
subtitle,
maxLines: 3,
overflow: TextOverflow.ellipsis,
)
: Container(),
EntityStateLabel(transactionRule),
],
),
),
);
}
}

View File

@ -0,0 +1,123 @@
import 'dart:async';
import 'package:invoiceninja_flutter/ui/app/tables/entity_list.dart';
import 'package:invoiceninja_flutter/ui/transaction_rule/transaction_rule_list_item.dart';
import 'package:invoiceninja_flutter/ui/transaction_rule/transaction_rule_presenter.dart';
import 'package:redux/redux.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:built_collection/built_collection.dart';
import 'package:invoiceninja_flutter/redux/ui/list_ui_state.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/redux/transaction_rule/transaction_rule_selectors.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/transaction_rule/transaction_rule_actions.dart';
class TransactionRuleListBuilder extends StatelessWidget {
const TransactionRuleListBuilder({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return StoreConnector<AppState, TransactionRuleListVM>(
converter: TransactionRuleListVM.fromStore,
builder: (context, viewModel) {
return EntityList(
entityType: EntityType.transactionRule,
presenter: TransactionRulePresenter(),
state: viewModel.state,
entityList: viewModel.transactionRuleList,
tableColumns: viewModel.tableColumns,
onRefreshed: viewModel.onRefreshed,
onSortColumn: viewModel.onSortColumn,
onClearMultiselect: viewModel.onClearMultielsect,
itemBuilder: (BuildContext context, index) {
final state = viewModel.state;
final transactionRuleId = viewModel.transactionRuleList[index];
final transactionRule =
viewModel.transactionRuleMap[transactionRuleId];
final listState = state.getListState(EntityType.transactionRule);
final isInMultiselect = listState.isInMultiselect();
return TransactionRuleListItem(
user: viewModel.state.user,
filter: viewModel.filter,
transactionRule: transactionRule,
isChecked:
isInMultiselect && listState.isSelected(transactionRule.id),
);
});
},
);
}
}
class TransactionRuleListVM {
TransactionRuleListVM({
@required this.state,
@required this.userCompany,
@required this.transactionRuleList,
@required this.transactionRuleMap,
@required this.filter,
@required this.isLoading,
@required this.listState,
@required this.onRefreshed,
@required this.onEntityAction,
@required this.tableColumns,
@required this.onSortColumn,
@required this.onClearMultielsect,
});
static TransactionRuleListVM fromStore(Store<AppState> store) {
Future<Null> _handleRefresh(BuildContext context) {
if (store.state.isLoading) {
return Future<Null>(null);
}
final completer = snackBarCompleter<Null>(
context, AppLocalization.of(context).refreshComplete);
store.dispatch(RefreshData(completer: completer));
return completer.future;
}
final state = store.state;
return TransactionRuleListVM(
state: state,
userCompany: state.userCompany,
listState: state.transactionRuleListState,
transactionRuleList: memoizedFilteredTransactionRuleList(
state.getUISelection(EntityType.transactionRule),
state.transactionRuleState.map,
state.transactionRuleState.list,
state.transactionRuleListState),
transactionRuleMap: state.transactionRuleState.map,
isLoading: state.isLoading,
filter: state.transactionRuleUIState.listUIState.filter,
onEntityAction: (BuildContext context, List<BaseEntity> transactionRules,
EntityAction action) =>
handleTransactionRuleAction(context, transactionRules, action),
onRefreshed: (context) => _handleRefresh(context),
tableColumns: state.userCompany.settings
?.getTableColumns(EntityType.transactionRule) ??
TransactionRulePresenter.getDefaultTableFields(state.userCompany),
onSortColumn: (field) => store.dispatch(SortTransactionRules(field)),
onClearMultielsect: () =>
store.dispatch(ClearTransactionRuleMultiselect()),
);
}
final AppState state;
final UserCompanyEntity userCompany;
final List<String> transactionRuleList;
final BuiltMap<String, TransactionRuleEntity> transactionRuleMap;
final ListUIState listState;
final String filter;
final bool isLoading;
final Function(BuildContext) onRefreshed;
final Function(BuildContext, List<BaseEntity>, EntityAction) onEntityAction;
final List<String> tableColumns;
final Function(String) onSortColumn;
final Function onClearMultielsect;
}

View File

@ -0,0 +1,27 @@
import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/ui/app/presenters/entity_presenter.dart';
class TransactionRulePresenter extends EntityPresenter {
static List<String> getDefaultTableFields(UserCompanyEntity userCompany) {
return [];
}
static List<String> getAllTableFields(UserCompanyEntity userCompany) {
return [
...getDefaultTableFields(userCompany),
...EntityPresenter.getBaseFields(),
];
}
@override
Widget getField({String field, BuildContext context}) {
//final state = StoreProvider.of<AppState>(context).state;
//final transactionRule = entity as TransactionRuleEntity;
switch (field) {
}
return super.getField(field: field, context: context);
}
}

View File

@ -0,0 +1,106 @@
import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/transaction_rule/transaction_rule_actions.dart';
import 'package:invoiceninja_flutter/ui/app/app_bottom_bar.dart';
import 'package:invoiceninja_flutter/ui/app/list_scaffold.dart';
import 'package:invoiceninja_flutter/ui/app/list_filter.dart';
import 'package:invoiceninja_flutter/ui/transaction_rule/transaction_rule_list_vm.dart';
import 'package:invoiceninja_flutter/ui/transaction_rule/transaction_rule_presenter.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
import 'transaction_rule_screen_vm.dart';
class TransactionRuleScreen extends StatelessWidget {
const TransactionRuleScreen({
Key key,
@required this.viewModel,
}) : super(key: key);
static const String route = '/transaction_rule';
final TransactionRuleScreenVM viewModel;
@override
Widget build(BuildContext context) {
final store = StoreProvider.of<AppState>(context);
final state = store.state;
final userCompany = state.userCompany;
final localization = AppLocalization.of(context);
return ListScaffold(
entityType: EntityType.transactionRule,
onHamburgerLongPress: () =>
store.dispatch(StartTransactionRuleMultiselect()),
appBarTitle: ListFilter(
key: ValueKey(
'__filter_${state.transactionRuleListState.filterClearedAt}__'),
entityType: EntityType.transactionRule,
entityIds: viewModel.transactionRuleList,
filter: state.transactionRuleListState.filter,
onFilterChanged: (value) {
store.dispatch(FilterTransactionRules(value));
},
onSelectedState: (EntityState state, value) {
store.dispatch(FilterTransactionRulesByState(state));
},
),
onCheckboxPressed: () {
if (store.state.transactionRuleListState.isInMultiselect()) {
store.dispatch(ClearTransactionRuleMultiselect());
} else {
store.dispatch(StartTransactionRuleMultiselect());
}
},
body: TransactionRuleListBuilder(),
bottomNavigationBar: AppBottomBar(
entityType: EntityType.transactionRule,
tableColumns: TransactionRulePresenter.getAllTableFields(userCompany),
defaultTableColumns:
TransactionRulePresenter.getDefaultTableFields(userCompany),
onSelectedSortField: (value) {
store.dispatch(SortTransactionRules(value));
},
sortFields: [
TransactionRuleFields.name,
],
onSelectedState: (EntityState state, value) {
store.dispatch(FilterTransactionRulesByState(state));
},
onCheckboxPressed: () {
if (store.state.transactionRuleListState.isInMultiselect()) {
store.dispatch(ClearTransactionRuleMultiselect());
} else {
store.dispatch(StartTransactionRuleMultiselect());
}
},
onSelectedCustom1: (value) =>
store.dispatch(FilterTransactionRulesByCustom1(value)),
onSelectedCustom2: (value) =>
store.dispatch(FilterTransactionRulesByCustom2(value)),
onSelectedCustom3: (value) =>
store.dispatch(FilterTransactionRulesByCustom3(value)),
onSelectedCustom4: (value) =>
store.dispatch(FilterTransactionRulesByCustom4(value)),
),
floatingActionButton: state.prefState.isMenuFloated &&
userCompany.canCreate(EntityType.transactionRule)
? FloatingActionButton(
heroTag: 'transaction_rule_fab',
backgroundColor: Theme.of(context).primaryColorDark,
onPressed: () {
createEntityByType(
context: context, entityType: EntityType.transactionRule);
},
child: Icon(
Icons.add,
color: Colors.white,
),
tooltip: localization.newTransactionRule,
)
: null,
);
}
}

View File

@ -0,0 +1,62 @@
import 'package:built_collection/built_collection.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/transaction_rule/transaction_rule_actions.dart';
import 'package:invoiceninja_flutter/redux/transaction_rule/transaction_rule_selectors.dart';
import 'package:redux/redux.dart';
import 'transaction_rule_screen.dart';
class TransactionRuleScreenBuilder extends StatelessWidget {
const TransactionRuleScreenBuilder({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return StoreConnector<AppState, TransactionRuleScreenVM>(
converter: TransactionRuleScreenVM.fromStore,
builder: (context, vm) {
return TransactionRuleScreen(
viewModel: vm,
);
},
);
}
}
class TransactionRuleScreenVM {
TransactionRuleScreenVM({
@required this.isInMultiselect,
@required this.transactionRuleList,
@required this.userCompany,
@required this.onEntityAction,
@required this.transactionRuleMap,
});
final bool isInMultiselect;
final UserCompanyEntity userCompany;
final List<String> transactionRuleList;
final Function(BuildContext, List<BaseEntity>, EntityAction) onEntityAction;
final BuiltMap<String, TransactionRuleEntity> transactionRuleMap;
static TransactionRuleScreenVM fromStore(Store<AppState> store) {
final state = store.state;
return TransactionRuleScreenVM(
transactionRuleMap: state.transactionRuleState.map,
transactionRuleList: memoizedFilteredTransactionRuleList(
state.getUISelection(EntityType.transactionRule),
state.transactionRuleState.map,
state.transactionRuleState.list,
state.transactionRuleListState,
),
userCompany: state.userCompany,
isInMultiselect: state.transactionRuleListState.isInMultiselect(),
onEntityAction: (BuildContext context, List<BaseEntity> transactionRules,
EntityAction action) =>
handleTransactionRuleAction(context, transactionRules, action),
);
}
}

View File

@ -0,0 +1,34 @@
import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/ui/app/scrollable_listview.dart';
import 'package:invoiceninja_flutter/ui/transaction_rule/view/transaction_rule_view_vm.dart';
import 'package:invoiceninja_flutter/ui/app/view_scaffold.dart';
class TransactionRuleView extends StatefulWidget {
const TransactionRuleView({
Key key,
@required this.viewModel,
@required this.isFilter,
}) : super(key: key);
final TransactionRuleViewVM viewModel;
final bool isFilter;
@override
_TransactionRuleViewState createState() => new _TransactionRuleViewState();
}
class _TransactionRuleViewState extends State<TransactionRuleView> {
@override
Widget build(BuildContext context) {
final viewModel = widget.viewModel;
final transactionRule = viewModel.transactionRule;
return ViewScaffold(
isFilter: widget.isFilter,
entity: transactionRule,
body: ScrollableListView(
children: <Widget>[],
),
);
}
}

View File

@ -0,0 +1,84 @@
import 'dart:async';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:redux/redux.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/redux/transaction_rule/transaction_rule_actions.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/ui/transaction_rule/view/transaction_rule_view.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
class TransactionRuleViewScreen extends StatelessWidget {
const TransactionRuleViewScreen({
Key key,
this.isFilter = false,
}) : super(key: key);
static const String route = '/transaction_rule/view';
final bool isFilter;
@override
Widget build(BuildContext context) {
return StoreConnector<AppState, TransactionRuleViewVM>(
converter: (Store<AppState> store) {
return TransactionRuleViewVM.fromStore(store);
},
builder: (context, vm) {
return TransactionRuleView(
viewModel: vm,
isFilter: isFilter,
);
},
);
}
}
class TransactionRuleViewVM {
TransactionRuleViewVM({
@required this.state,
@required this.transactionRule,
@required this.company,
@required this.onEntityAction,
@required this.onRefreshed,
@required this.isSaving,
@required this.isLoading,
@required this.isDirty,
});
factory TransactionRuleViewVM.fromStore(Store<AppState> store) {
final state = store.state;
final transactionRule = state.transactionRuleState
.map[state.transactionRuleUIState.selectedId] ??
TransactionRuleEntity(id: state.transactionRuleUIState.selectedId);
Future<Null> _handleRefresh(BuildContext context) {
final completer = snackBarCompleter<Null>(
context, AppLocalization.of(context).refreshComplete);
store.dispatch(LoadTransactionRule(
completer: completer, transactionRuleId: transactionRule.id));
return completer.future;
}
return TransactionRuleViewVM(
state: state,
company: state.company,
isSaving: state.isSaving,
isLoading: state.isLoading,
isDirty: transactionRule.isNew,
transactionRule: transactionRule,
onRefreshed: (context) => _handleRefresh(context),
onEntityAction: (BuildContext context, EntityAction action) =>
handleEntitiesActions([transactionRule], action, autoPop: true),
);
}
final AppState state;
final TransactionRuleEntity transactionRule;
final CompanyEntity company;
final Function(BuildContext, EntityAction) onEntityAction;
final Function(BuildContext) onRefreshed;
final bool isSaving;
final bool isLoading;
final bool isDirty;
}

View File

@ -16,6 +16,18 @@ mixin LocalizationsProvider on LocaleCodeAware {
static final Map<String, Map<String, String>> _localizedValues = {
'en': {
// STARTER: lang key - do not remove comment
'transaction_rule': 'Transaction Rule',
'transaction_rules': 'Transaction Rules',
'new_transaction_rule': 'New Transaction Rule',
'edit_transaction_rule': 'Edit Transaction Rule',
'created_transaction_rule': 'Successfully created rule',
'updated_transaction_rule': 'Successfully updated transaction rule',
'archived_transaction_rule': 'Successfully archived transaction rule',
'deleted_transaction_rule': 'Successfully deleted transaction rule',
'removed_transaction_rule': 'Successfully removed transaction rule',
'restored_transaction_rule': 'Successfully restored transaction rule',
'search_transaction_rule': 'Search Transaction Rule',
'search_transaction_rules': 'Search Transaction Rules',
'save_as_default_terms': 'Save as default terms',
'save_as_default_footer': 'Save as default footer',
'auto_sync': 'Auto Sync',
@ -90453,6 +90465,39 @@ mixin LocalizationsProvider on LocaleCodeAware {
_localizedValues['en']['save_as_default_footer'];
// STARTER: lang field - do not remove comment
String get transactionRule =>
_localizedValues[localeCode]['transaction_rule'] ??
_localizedValues['en']['transaction_rule'];
String get transactionRules =>
_localizedValues[localeCode]['transaction_rules'] ??
_localizedValues['en']['transaction_rules'];
String get newTransactionRule =>
_localizedValues[localeCode]['new_transaction_rule'] ??
_localizedValues['en']['new_transaction_rule'];
String get createdTransactionRule =>
_localizedValues[localeCode]['created_transaction_rule'] ??
_localizedValues['en']['created_transaction_rule'];
String get updatedTransactionRule =>
_localizedValues[localeCode]['updated_transaction_rule'] ??
_localizedValues['en']['updated_transaction_rule'];
String get archivedTransactionRule =>
_localizedValues[localeCode]['archived_transaction_rule'] ??
_localizedValues['en']['archived_transaction_rule'];
String get deletedTransactionRule =>
_localizedValues[localeCode]['deleted_transaction_rule'] ??
_localizedValues['en']['deleted_transaction_rule'];
String get restoredTransactionRule =>
_localizedValues[localeCode]['restored_transaction_rule'] ??
_localizedValues['en']['restored_transaction_rule'];
String get editTransactionRule =>
_localizedValues[localeCode]['edit_transaction_rule'] ??
_localizedValues['en']['edit_transaction_rule'];
String get searchTransactionRule =>
_localizedValues[localeCode]['search_transaction_rule'] ??
_localizedValues['en']['search_transaction_rule'];
String get searchTransactionRule =>
_localizedValues[localeCode]['search_transaction_rules'] ??
_localizedValues['en']['search_transaction_rules'];
String lookup(String key) {
final lookupKey = toSnakeCase(key);

View File

@ -188,7 +188,7 @@ else
echo "app_state: import"
comment="STARTER: import - do not remove comment"
code="import 'package:${package}\/redux\/${module_snake}\/${module_snake}_state.dart';import 'package:${package}\/ui\/${module_snake}\/edit\/${module_snake}_edit_vm.dart';${lineBreak}"
sed -i -e "s/$comment/$code${lineBreak}$comment/g" ./lib/redux/app/app_state.dart
sed -i -e "s/$comment/$comment${lineBreak}$code/g" ./lib/redux/app/app_state.dart
echo "app_state: list"
comment="STARTER: states switch list - do not remove comment"
@ -308,7 +308,7 @@ else
echo "main: import"
comment="STARTER: import - do not remove comment"
code="import 'package:${package}\/redux\/${module_snake}\/${module_snake}_middleware.dart';${lineBreak}"
sed -i -e "s/$code/$code${lineBreak}$comment/g" ./lib/main.dart
sed -i -e "s/$code/$comment${lineBreak}$code/g" ./lib/main.dart
comment="STARTER: middleware - do not remove comment"
code="..addAll(createStore${Modules}Middleware())${lineBreak}"
@ -319,7 +319,7 @@ else
code="${code}import 'package:${package}\/ui\/${module_snake}\/edit\/${module_snake}_edit_vm.dart';${lineBreak}"
code="${code}import 'package:${package}\/ui\/${module_snake}\/view\/${module_snake}_view_vm.dart';${lineBreak}"
code="${code}import 'package:${package}\/ui\/${module_snake}\/${module_snake}_screen_vm.dart';${lineBreak}"
sed -i -e "s/$comment/$code${lineBreak}$comment/g" ./lib/main_app.dart
sed -i -e "s/$comment/$comment${lineBreak}$code/g" ./lib/main_app.dart
comment="STARTER: routes - do not remove comment"
code="${Module}Screen.route: (context) => ${Module}ScreenBuilder(),${lineBreak}"
@ -333,7 +333,7 @@ else
comment="STARTER: import - do not remove comment"
code="import 'package:${package}\/redux\/${module_snake}\/${module_snake}_state.dart';${lineBreak}"
sed -i -e "s/$comment/$code${lineBreak}$comment/g" ./lib/data/models/serializers.dart
sed -i -e "s/$comment/$comment${lineBreak}$code/g" ./lib/data/models/serializers.dart
comment="STARTER: serializers - do not remove comment"
code="${Module}Entity,${lineBreak}${Module}ListResponse,${lineBreak}${Module}ItemResponse,${lineBreak}"
@ -341,7 +341,7 @@ else
comment="STARTER: import - do not remove comment"
code="import 'package:${package}\/redux\/${module_snake}\/${module_snake}_state.dart';${lineBreak}"
sed -i -e "s/$comment/$code${lineBreak}$comment/g" ./lib/redux/company/company_state.dart
sed -i -e "s/$comment/$comment${lineBreak}$code/g" ./lib/redux/company/company_state.dart
comment="STARTER: fields - do not remove comment"
code="${Module}State get ${module_camel}State;${lineBreak}"
@ -353,7 +353,7 @@ else
comment="STARTER: import - do not remove comment"
code="import 'package:${package}\/redux\/${module_snake}\/${module_snake}_reducer.dart';${lineBreak}"
sed -i -e "s/$comment/$code${lineBreak}$comment/g" ./lib/redux/company/company_reducer.dart
sed -i -e "s/$comment/$comment${lineBreak}$code/g" ./lib/redux/company/company_reducer.dart
comment="STARTER: reducer - do not remove comment"
code="..${module_camel}State.replace(${modules_camel}Reducer(state.${module_camel}State, action))${lineBreak}"
@ -370,7 +370,7 @@ else
comment="STARTER: import - do not remove comment"
code="import 'package:${package}\/redux\/${module_snake}\/${module_snake}_state.dart';${lineBreak}"
sed -i -e "s/$comment/$code${lineBreak}$comment/g" ./lib/redux/ui/ui_state.dart
sed -i -e "s/$comment/$comment${lineBreak}$code/g" ./lib/redux/ui/ui_state.dart
comment="STARTER: properties - do not remove comment"
code="${Module}UIState get ${module_camel}UIState;${lineBreak}"
@ -382,7 +382,7 @@ else
comment="STARTER: import - do not remove comment"
code="import 'package:${package}\/redux\/${module_snake}\/${module_snake}_reducer.dart';${lineBreak}"
sed -i -e "s/$comment/$code${lineBreak}$comment/g" ./lib/redux/ui/ui_reducer.dart
sed -i -e "s/$comment/$comment${lineBreak}$code/g" ./lib/redux/ui/ui_reducer.dart
comment="STARTER: reducer - do not remove comment"
code="..${module_camel}UIState.replace(${module_camel}UIReducer(state.${module_camel}UIState, action))${lineBreak}"
@ -390,7 +390,7 @@ else
comment="STARTER: import - do not remove comment"
code="import 'package:${package}\/redux\/${module_snake}\/${module_snake}_actions.dart';${lineBreak}"
sed -i -e "s/$comment/$code${lineBreak}$comment/g" ./lib/redux/app/app_reducer.dart
sed -i -e "s/$comment/$comment${lineBreak}$code/g" ./lib/redux/app/app_reducer.dart
comment="STARTER: errors - do not remove comment"
code="TypedReducer<String, Load${Modules}Failure>((state, action) { return '\${action.error}'; }),${lineBreak}"
@ -402,11 +402,11 @@ else
comment="STARTER: import - do not remove comment"
code="import 'package:${package}\/redux\/${module_snake}\/${module_snake}_actions.dart';${lineBreak}"
sed -i -e "s/$comment/$code${lineBreak}$comment/g" ./lib/redux/ui/pref_reducer.dart
sed -i -e "s/$comment/$comment${lineBreak}$code/g" ./lib/redux/ui/pref_reducer.dart
comment="STARTER: import - do not remove comment"
code="import 'package:${package}\/redux\/${module_snake}\/${module_snake}_actions.dart';${lineBreak}"
sed -i -e "s/$comment/$code${lineBreak}$comment/g" ./lib/redux/app/app_actions.dart
sed -i -e "s/$comment/$comment${lineBreak}$code/g" ./lib/redux/app/app_actions.dart
comment="STARTER: view list - do not remove comment"
code="case EntityType.${module_camel}: action = View${Module}List(); break;${lineBreak}"

View File

@ -51,7 +51,6 @@ abstract class StubEntity extends Object with BaseEntity implements Built<StubEn
factory StubEntity({String id, AppState state}) {
return _$StubEntity._(
id: id ?? BaseEntity.nextId,
idempotencyKey: BaseEntity.nextIdempotencyKey,
isChanged: false,
isDeleted: false,
createdAt: 0,