Payment terms

This commit is contained in:
Hillel Coren 2020-05-25 20:14:07 +03:00
parent bc39ce9f20
commit b1aac6e1fb
45 changed files with 4564 additions and 1304 deletions

View File

@ -10,6 +10,7 @@ import 'package:invoiceninja_flutter/data/models/company_gateway_model.dart';
import 'package:invoiceninja_flutter/data/models/entities.dart';
import 'package:invoiceninja_flutter/data/models/group_model.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/data/models/payment_term_model.dart';
import 'package:invoiceninja_flutter/data/models/task_model.dart';
import 'package:invoiceninja_flutter/utils/formatting.dart';
import 'package:invoiceninja_flutter/.env.dart';
@ -364,44 +365,6 @@ abstract class CompanyEntity extends Object
static Serializer<CompanyEntity> get serializer => _$companyEntitySerializer;
}
abstract class PaymentTermEntity extends Object
with SelectableEntity
implements Built<PaymentTermEntity, PaymentTermEntityBuilder> {
factory PaymentTermEntity() {
return _$PaymentTermEntity._(
id: BaseEntity.nextId,
numDays: 0,
);
}
PaymentTermEntity._();
@override
@memoized
int get hashCode;
static Serializer<PaymentTermEntity> get serializer =>
_$paymentTermEntitySerializer;
String getPaymentTerm(String netLabel) {
if (numDays == 0) {
return '';
} else if (numDays == -1) {
return '$netLabel 0';
} else {
return '$netLabel $numDays';
}
}
@nullable
@BuiltValueField(wireName: 'num_days')
int get numDays;
@nullable
@BuiltValueField(wireName: 'archived_at')
int get archivedAt;
}
abstract class GatewayEntity extends Object
with SelectableEntity
implements Built<GatewayEntity, GatewayEntityBuilder> {

View File

@ -8,8 +8,6 @@ part of 'company_model.dart';
Serializer<CompanyEntity> _$companyEntitySerializer =
new _$CompanyEntitySerializer();
Serializer<PaymentTermEntity> _$paymentTermEntitySerializer =
new _$PaymentTermEntitySerializer();
Serializer<GatewayEntity> _$gatewayEntitySerializer =
new _$GatewayEntitySerializer();
Serializer<UserCompanyEntity> _$userCompanyEntitySerializer =
@ -555,69 +553,6 @@ class _$CompanyEntitySerializer implements StructuredSerializer<CompanyEntity> {
}
}
class _$PaymentTermEntitySerializer
implements StructuredSerializer<PaymentTermEntity> {
@override
final Iterable<Type> types = const [PaymentTermEntity, _$PaymentTermEntity];
@override
final String wireName = 'PaymentTermEntity';
@override
Iterable<Object> serialize(Serializers serializers, PaymentTermEntity object,
{FullType specifiedType = FullType.unspecified}) {
final result = <Object>[];
if (object.numDays != null) {
result
..add('num_days')
..add(serializers.serialize(object.numDays,
specifiedType: const FullType(int)));
}
if (object.archivedAt != null) {
result
..add('archived_at')
..add(serializers.serialize(object.archivedAt,
specifiedType: const FullType(int)));
}
if (object.id != null) {
result
..add('id')
..add(serializers.serialize(object.id,
specifiedType: const FullType(String)));
}
return result;
}
@override
PaymentTermEntity deserialize(
Serializers serializers, Iterable<Object> serialized,
{FullType specifiedType = FullType.unspecified}) {
final result = new PaymentTermEntityBuilder();
final iterator = serialized.iterator;
while (iterator.moveNext()) {
final key = iterator.current as String;
iterator.moveNext();
final dynamic value = iterator.current;
switch (key) {
case 'num_days':
result.numDays = 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 'id':
result.id = serializers.deserialize(value,
specifiedType: const FullType(String)) as String;
break;
}
}
return result.build();
}
}
class _$GatewayEntitySerializer implements StructuredSerializer<GatewayEntity> {
@override
final Iterable<Type> types = const [GatewayEntity, _$GatewayEntity];
@ -3683,105 +3618,6 @@ class CompanyEntityBuilder
}
}
class _$PaymentTermEntity extends PaymentTermEntity {
@override
final int numDays;
@override
final int archivedAt;
@override
final String id;
factory _$PaymentTermEntity(
[void Function(PaymentTermEntityBuilder) updates]) =>
(new PaymentTermEntityBuilder()..update(updates)).build();
_$PaymentTermEntity._({this.numDays, this.archivedAt, this.id}) : super._();
@override
PaymentTermEntity rebuild(void Function(PaymentTermEntityBuilder) updates) =>
(toBuilder()..update(updates)).build();
@override
PaymentTermEntityBuilder toBuilder() =>
new PaymentTermEntityBuilder()..replace(this);
@override
bool operator ==(Object other) {
if (identical(other, this)) return true;
return other is PaymentTermEntity &&
numDays == other.numDays &&
archivedAt == other.archivedAt &&
id == other.id;
}
int __hashCode;
@override
int get hashCode {
return __hashCode ??= $jf(
$jc($jc($jc(0, numDays.hashCode), archivedAt.hashCode), id.hashCode));
}
@override
String toString() {
return (newBuiltValueToStringHelper('PaymentTermEntity')
..add('numDays', numDays)
..add('archivedAt', archivedAt)
..add('id', id))
.toString();
}
}
class PaymentTermEntityBuilder
implements Builder<PaymentTermEntity, PaymentTermEntityBuilder> {
_$PaymentTermEntity _$v;
int _numDays;
int get numDays => _$this._numDays;
set numDays(int numDays) => _$this._numDays = numDays;
int _archivedAt;
int get archivedAt => _$this._archivedAt;
set archivedAt(int archivedAt) => _$this._archivedAt = archivedAt;
String _id;
String get id => _$this._id;
set id(String id) => _$this._id = id;
PaymentTermEntityBuilder();
PaymentTermEntityBuilder get _$this {
if (_$v != null) {
_numDays = _$v.numDays;
_archivedAt = _$v.archivedAt;
_id = _$v.id;
_$v = null;
}
return this;
}
@override
void replace(PaymentTermEntity other) {
if (other == null) {
throw new ArgumentError.notNull('other');
}
_$v = other as _$PaymentTermEntity;
}
@override
void update(void Function(PaymentTermEntityBuilder) updates) {
if (updates != null) updates(this);
}
@override
_$PaymentTermEntity build() {
final _$result = _$v ??
new _$PaymentTermEntity._(
numDays: numDays, archivedAt: archivedAt, id: id);
replace(_$result);
return _$result;
}
}
class _$GatewayEntity extends GatewayEntity {
@override
final String id;

View File

@ -16,7 +16,6 @@ class EntityType extends EnumClass {
static const EntityType dashboard = _$dashboard;
static const EntityType reports = _$reports;
static const EntityType settings = _$settings;
static const EntityType taxRate = _$taxRate;
static const EntityType companyGateway = _$companyGateway;
static const EntityType invoice = _$invoice;
@ -38,8 +37,8 @@ class EntityType extends EnumClass {
static const EntityType gatewayToken = _$gatewayToken;
static const EntityType invoiceItem = _$invoiceItem;
static const EntityType design = _$design;
// STARTER: entity type - do not remove comment
static const EntityType paymentTerm = _$paymentTerm;
static const EntityType quoteItem = _$quoteItem;
static const EntityType contact = _$contact;
static const EntityType vendorContact = _$vendorContact;

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 _$paymentTerm = const EntityType._('paymentTerm');
const EntityType _$quoteItem = const EntityType._('quoteItem');
const EntityType _$contact = const EntityType._('contact');
const EntityType _$vendorContact = const EntityType._('vendorContact');
@ -95,6 +96,8 @@ EntityType _$typeValueOf(String name) {
return _$invoiceItem;
case 'design':
return _$design;
case 'paymentTerm':
return _$paymentTerm;
case 'quoteItem':
return _$quoteItem;
case 'contact':
@ -154,6 +157,7 @@ final BuiltSet<EntityType> _$typeValues =
_$gatewayToken,
_$invoiceItem,
_$design,
_$paymentTerm,
_$quoteItem,
_$contact,
_$vendorContact,

View File

@ -0,0 +1,88 @@
import 'package:built_collection/built_collection.dart';
import 'package:built_value/built_value.dart';
import 'package:built_value/serializer.dart';
import 'package:invoiceninja_flutter/data/models/entities.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
part 'payment_term_model.g.dart';
abstract class PaymentTermListResponse
implements Built<PaymentTermListResponse, PaymentTermListResponseBuilder> {
factory PaymentTermListResponse(
[void updates(PaymentTermListResponseBuilder b)]) =
_$PaymentTermListResponse;
PaymentTermListResponse._();
@override
@memoized
int get hashCode;
BuiltList<PaymentTermEntity> get data;
static Serializer<PaymentTermListResponse> get serializer =>
_$paymentTermListResponseSerializer;
}
abstract class PaymentTermItemResponse
implements Built<PaymentTermItemResponse, PaymentTermItemResponseBuilder> {
factory PaymentTermItemResponse(
[void updates(PaymentTermItemResponseBuilder b)]) =
_$PaymentTermItemResponse;
PaymentTermItemResponse._();
@override
@memoized
int get hashCode;
PaymentTermEntity get data;
static Serializer<PaymentTermItemResponse> get serializer =>
_$paymentTermItemResponseSerializer;
}
class PaymentTermFields {
static const String name = 'name';
static const String numDays = 'num_days';
}
abstract class PaymentTermEntity extends Object
with BaseEntity, SelectableEntity
implements Built<PaymentTermEntity, PaymentTermEntityBuilder> {
factory PaymentTermEntity({String id, AppState state}) {
return _$PaymentTermEntity._(
id: id ?? BaseEntity.nextId,
numDays: 0,
name: '',
);
}
PaymentTermEntity._();
@override
@memoized
int get hashCode;
static Serializer<PaymentTermEntity> get serializer =>
_$paymentTermEntitySerializer;
String getPaymentTerm(String netLabel) {
if (numDays == 0) {
return '';
} else if (numDays == -1) {
return '$netLabel 0';
} else {
return '$netLabel $numDays';
}
}
String get name;
@BuiltValueField(wireName: 'num_days')
int get numDays;
int compareTo(PaymentTermEntity paymentTerm, String sortField,
bool sortAscending) =>
numDays.compareTo(paymentTerm.numDays);
}

View File

@ -0,0 +1,663 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'payment_term_model.dart';
// **************************************************************************
// BuiltValueGenerator
// **************************************************************************
Serializer<PaymentTermListResponse> _$paymentTermListResponseSerializer =
new _$PaymentTermListResponseSerializer();
Serializer<PaymentTermItemResponse> _$paymentTermItemResponseSerializer =
new _$PaymentTermItemResponseSerializer();
Serializer<PaymentTermEntity> _$paymentTermEntitySerializer =
new _$PaymentTermEntitySerializer();
class _$PaymentTermListResponseSerializer
implements StructuredSerializer<PaymentTermListResponse> {
@override
final Iterable<Type> types = const [
PaymentTermListResponse,
_$PaymentTermListResponse
];
@override
final String wireName = 'PaymentTermListResponse';
@override
Iterable<Object> serialize(
Serializers serializers, PaymentTermListResponse object,
{FullType specifiedType = FullType.unspecified}) {
final result = <Object>[
'data',
serializers.serialize(object.data,
specifiedType: const FullType(
BuiltList, const [const FullType(PaymentTermEntity)])),
];
return result;
}
@override
PaymentTermListResponse deserialize(
Serializers serializers, Iterable<Object> serialized,
{FullType specifiedType = FullType.unspecified}) {
final result = new PaymentTermListResponseBuilder();
final iterator = serialized.iterator;
while (iterator.moveNext()) {
final key = iterator.current as String;
iterator.moveNext();
final dynamic value = iterator.current;
switch (key) {
case 'data':
result.data.replace(serializers.deserialize(value,
specifiedType: const FullType(
BuiltList, const [const FullType(PaymentTermEntity)]))
as BuiltList<Object>);
break;
}
}
return result.build();
}
}
class _$PaymentTermItemResponseSerializer
implements StructuredSerializer<PaymentTermItemResponse> {
@override
final Iterable<Type> types = const [
PaymentTermItemResponse,
_$PaymentTermItemResponse
];
@override
final String wireName = 'PaymentTermItemResponse';
@override
Iterable<Object> serialize(
Serializers serializers, PaymentTermItemResponse object,
{FullType specifiedType = FullType.unspecified}) {
final result = <Object>[
'data',
serializers.serialize(object.data,
specifiedType: const FullType(PaymentTermEntity)),
];
return result;
}
@override
PaymentTermItemResponse deserialize(
Serializers serializers, Iterable<Object> serialized,
{FullType specifiedType = FullType.unspecified}) {
final result = new PaymentTermItemResponseBuilder();
final iterator = serialized.iterator;
while (iterator.moveNext()) {
final key = iterator.current as String;
iterator.moveNext();
final dynamic value = iterator.current;
switch (key) {
case 'data':
result.data.replace(serializers.deserialize(value,
specifiedType: const FullType(PaymentTermEntity))
as PaymentTermEntity);
break;
}
}
return result.build();
}
}
class _$PaymentTermEntitySerializer
implements StructuredSerializer<PaymentTermEntity> {
@override
final Iterable<Type> types = const [PaymentTermEntity, _$PaymentTermEntity];
@override
final String wireName = 'PaymentTermEntity';
@override
Iterable<Object> serialize(Serializers serializers, PaymentTermEntity object,
{FullType specifiedType = FullType.unspecified}) {
final result = <Object>[
'name',
serializers.serialize(object.name, specifiedType: const FullType(String)),
'num_days',
serializers.serialize(object.numDays, specifiedType: const FullType(int)),
];
if (object.isChanged != null) {
result
..add('isChanged')
..add(serializers.serialize(object.isChanged,
specifiedType: const FullType(bool)));
}
if (object.createdAt != null) {
result
..add('created_at')
..add(serializers.serialize(object.createdAt,
specifiedType: const FullType(int)));
}
if (object.updatedAt != null) {
result
..add('updated_at')
..add(serializers.serialize(object.updatedAt,
specifiedType: const FullType(int)));
}
if (object.archivedAt != null) {
result
..add('archived_at')
..add(serializers.serialize(object.archivedAt,
specifiedType: const FullType(int)));
}
if (object.isDeleted != null) {
result
..add('is_deleted')
..add(serializers.serialize(object.isDeleted,
specifiedType: const FullType(bool)));
}
if (object.createdUserId != null) {
result
..add('user_id')
..add(serializers.serialize(object.createdUserId,
specifiedType: const FullType(String)));
}
if (object.assignedUserId != null) {
result
..add('assigned_user_id')
..add(serializers.serialize(object.assignedUserId,
specifiedType: const FullType(String)));
}
if (object.subEntityType != null) {
result
..add('entity_type')
..add(serializers.serialize(object.subEntityType,
specifiedType: const FullType(EntityType)));
}
if (object.id != null) {
result
..add('id')
..add(serializers.serialize(object.id,
specifiedType: const FullType(String)));
}
return result;
}
@override
PaymentTermEntity deserialize(
Serializers serializers, Iterable<Object> serialized,
{FullType specifiedType = FullType.unspecified}) {
final result = new PaymentTermEntityBuilder();
final iterator = serialized.iterator;
while (iterator.moveNext()) {
final key = iterator.current as String;
iterator.moveNext();
final dynamic value = iterator.current;
switch (key) {
case 'name':
result.name = serializers.deserialize(value,
specifiedType: const FullType(String)) as String;
break;
case 'num_days':
result.numDays = serializers.deserialize(value,
specifiedType: const FullType(int)) as int;
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 'entity_type':
result.subEntityType = serializers.deserialize(value,
specifiedType: const FullType(EntityType)) as EntityType;
break;
case 'id':
result.id = serializers.deserialize(value,
specifiedType: const FullType(String)) as String;
break;
}
}
return result.build();
}
}
class _$PaymentTermListResponse extends PaymentTermListResponse {
@override
final BuiltList<PaymentTermEntity> data;
factory _$PaymentTermListResponse(
[void Function(PaymentTermListResponseBuilder) updates]) =>
(new PaymentTermListResponseBuilder()..update(updates)).build();
_$PaymentTermListResponse._({this.data}) : super._() {
if (data == null) {
throw new BuiltValueNullFieldError('PaymentTermListResponse', 'data');
}
}
@override
PaymentTermListResponse rebuild(
void Function(PaymentTermListResponseBuilder) updates) =>
(toBuilder()..update(updates)).build();
@override
PaymentTermListResponseBuilder toBuilder() =>
new PaymentTermListResponseBuilder()..replace(this);
@override
bool operator ==(Object other) {
if (identical(other, this)) return true;
return other is PaymentTermListResponse && data == other.data;
}
int __hashCode;
@override
int get hashCode {
return __hashCode ??= $jf($jc(0, data.hashCode));
}
@override
String toString() {
return (newBuiltValueToStringHelper('PaymentTermListResponse')
..add('data', data))
.toString();
}
}
class PaymentTermListResponseBuilder
implements
Builder<PaymentTermListResponse, PaymentTermListResponseBuilder> {
_$PaymentTermListResponse _$v;
ListBuilder<PaymentTermEntity> _data;
ListBuilder<PaymentTermEntity> get data =>
_$this._data ??= new ListBuilder<PaymentTermEntity>();
set data(ListBuilder<PaymentTermEntity> data) => _$this._data = data;
PaymentTermListResponseBuilder();
PaymentTermListResponseBuilder get _$this {
if (_$v != null) {
_data = _$v.data?.toBuilder();
_$v = null;
}
return this;
}
@override
void replace(PaymentTermListResponse other) {
if (other == null) {
throw new ArgumentError.notNull('other');
}
_$v = other as _$PaymentTermListResponse;
}
@override
void update(void Function(PaymentTermListResponseBuilder) updates) {
if (updates != null) updates(this);
}
@override
_$PaymentTermListResponse build() {
_$PaymentTermListResponse _$result;
try {
_$result = _$v ?? new _$PaymentTermListResponse._(data: data.build());
} catch (_) {
String _$failedField;
try {
_$failedField = 'data';
data.build();
} catch (e) {
throw new BuiltValueNestedFieldError(
'PaymentTermListResponse', _$failedField, e.toString());
}
rethrow;
}
replace(_$result);
return _$result;
}
}
class _$PaymentTermItemResponse extends PaymentTermItemResponse {
@override
final PaymentTermEntity data;
factory _$PaymentTermItemResponse(
[void Function(PaymentTermItemResponseBuilder) updates]) =>
(new PaymentTermItemResponseBuilder()..update(updates)).build();
_$PaymentTermItemResponse._({this.data}) : super._() {
if (data == null) {
throw new BuiltValueNullFieldError('PaymentTermItemResponse', 'data');
}
}
@override
PaymentTermItemResponse rebuild(
void Function(PaymentTermItemResponseBuilder) updates) =>
(toBuilder()..update(updates)).build();
@override
PaymentTermItemResponseBuilder toBuilder() =>
new PaymentTermItemResponseBuilder()..replace(this);
@override
bool operator ==(Object other) {
if (identical(other, this)) return true;
return other is PaymentTermItemResponse && data == other.data;
}
int __hashCode;
@override
int get hashCode {
return __hashCode ??= $jf($jc(0, data.hashCode));
}
@override
String toString() {
return (newBuiltValueToStringHelper('PaymentTermItemResponse')
..add('data', data))
.toString();
}
}
class PaymentTermItemResponseBuilder
implements
Builder<PaymentTermItemResponse, PaymentTermItemResponseBuilder> {
_$PaymentTermItemResponse _$v;
PaymentTermEntityBuilder _data;
PaymentTermEntityBuilder get data =>
_$this._data ??= new PaymentTermEntityBuilder();
set data(PaymentTermEntityBuilder data) => _$this._data = data;
PaymentTermItemResponseBuilder();
PaymentTermItemResponseBuilder get _$this {
if (_$v != null) {
_data = _$v.data?.toBuilder();
_$v = null;
}
return this;
}
@override
void replace(PaymentTermItemResponse other) {
if (other == null) {
throw new ArgumentError.notNull('other');
}
_$v = other as _$PaymentTermItemResponse;
}
@override
void update(void Function(PaymentTermItemResponseBuilder) updates) {
if (updates != null) updates(this);
}
@override
_$PaymentTermItemResponse build() {
_$PaymentTermItemResponse _$result;
try {
_$result = _$v ?? new _$PaymentTermItemResponse._(data: data.build());
} catch (_) {
String _$failedField;
try {
_$failedField = 'data';
data.build();
} catch (e) {
throw new BuiltValueNestedFieldError(
'PaymentTermItemResponse', _$failedField, e.toString());
}
rethrow;
}
replace(_$result);
return _$result;
}
}
class _$PaymentTermEntity extends PaymentTermEntity {
@override
final String name;
@override
final int numDays;
@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 EntityType subEntityType;
@override
final String id;
factory _$PaymentTermEntity(
[void Function(PaymentTermEntityBuilder) updates]) =>
(new PaymentTermEntityBuilder()..update(updates)).build();
_$PaymentTermEntity._(
{this.name,
this.numDays,
this.isChanged,
this.createdAt,
this.updatedAt,
this.archivedAt,
this.isDeleted,
this.createdUserId,
this.assignedUserId,
this.subEntityType,
this.id})
: super._() {
if (name == null) {
throw new BuiltValueNullFieldError('PaymentTermEntity', 'name');
}
if (numDays == null) {
throw new BuiltValueNullFieldError('PaymentTermEntity', 'numDays');
}
}
@override
PaymentTermEntity rebuild(void Function(PaymentTermEntityBuilder) updates) =>
(toBuilder()..update(updates)).build();
@override
PaymentTermEntityBuilder toBuilder() =>
new PaymentTermEntityBuilder()..replace(this);
@override
bool operator ==(Object other) {
if (identical(other, this)) return true;
return other is PaymentTermEntity &&
name == other.name &&
numDays == other.numDays &&
isChanged == other.isChanged &&
createdAt == other.createdAt &&
updatedAt == other.updatedAt &&
archivedAt == other.archivedAt &&
isDeleted == other.isDeleted &&
createdUserId == other.createdUserId &&
assignedUserId == other.assignedUserId &&
subEntityType == other.subEntityType &&
id == other.id;
}
int __hashCode;
@override
int get hashCode {
return __hashCode ??= $jf($jc(
$jc(
$jc(
$jc(
$jc(
$jc(
$jc(
$jc(
$jc(
$jc($jc(0, name.hashCode),
numDays.hashCode),
isChanged.hashCode),
createdAt.hashCode),
updatedAt.hashCode),
archivedAt.hashCode),
isDeleted.hashCode),
createdUserId.hashCode),
assignedUserId.hashCode),
subEntityType.hashCode),
id.hashCode));
}
@override
String toString() {
return (newBuiltValueToStringHelper('PaymentTermEntity')
..add('name', name)
..add('numDays', numDays)
..add('isChanged', isChanged)
..add('createdAt', createdAt)
..add('updatedAt', updatedAt)
..add('archivedAt', archivedAt)
..add('isDeleted', isDeleted)
..add('createdUserId', createdUserId)
..add('assignedUserId', assignedUserId)
..add('subEntityType', subEntityType)
..add('id', id))
.toString();
}
}
class PaymentTermEntityBuilder
implements Builder<PaymentTermEntity, PaymentTermEntityBuilder> {
_$PaymentTermEntity _$v;
String _name;
String get name => _$this._name;
set name(String name) => _$this._name = name;
int _numDays;
int get numDays => _$this._numDays;
set numDays(int numDays) => _$this._numDays = numDays;
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;
EntityType _subEntityType;
EntityType get subEntityType => _$this._subEntityType;
set subEntityType(EntityType subEntityType) =>
_$this._subEntityType = subEntityType;
String _id;
String get id => _$this._id;
set id(String id) => _$this._id = id;
PaymentTermEntityBuilder();
PaymentTermEntityBuilder get _$this {
if (_$v != null) {
_name = _$v.name;
_numDays = _$v.numDays;
_isChanged = _$v.isChanged;
_createdAt = _$v.createdAt;
_updatedAt = _$v.updatedAt;
_archivedAt = _$v.archivedAt;
_isDeleted = _$v.isDeleted;
_createdUserId = _$v.createdUserId;
_assignedUserId = _$v.assignedUserId;
_subEntityType = _$v.subEntityType;
_id = _$v.id;
_$v = null;
}
return this;
}
@override
void replace(PaymentTermEntity other) {
if (other == null) {
throw new ArgumentError.notNull('other');
}
_$v = other as _$PaymentTermEntity;
}
@override
void update(void Function(PaymentTermEntityBuilder) updates) {
if (updates != null) updates(this);
}
@override
_$PaymentTermEntity build() {
final _$result = _$v ??
new _$PaymentTermEntity._(
name: name,
numDays: numDays,
isChanged: isChanged,
createdAt: createdAt,
updatedAt: updatedAt,
archivedAt: archivedAt,
isDeleted: isDeleted,
createdUserId: createdUserId,
assignedUserId: assignedUserId,
subEntityType: subEntityType,
id: 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,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

@ -12,6 +12,7 @@ import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/data/models/entities.dart';
import 'package:invoiceninja_flutter/data/models/payment_model.dart';
import 'package:invoiceninja_flutter/data/models/account_model.dart';
import 'package:invoiceninja_flutter/data/models/payment_term_model.dart';
import 'package:invoiceninja_flutter/data/models/project_model.dart';
import 'package:invoiceninja_flutter/data/models/task_model.dart';
import 'package:invoiceninja_flutter/data/models/tax_rate_model.dart';
@ -35,7 +36,9 @@ import 'package:invoiceninja_flutter/redux/task/task_state.dart';
import 'package:invoiceninja_flutter/redux/project/project_state.dart';
import 'package:invoiceninja_flutter/redux/payment/payment_state.dart';
import 'package:invoiceninja_flutter/redux/quote/quote_state.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/redux/payment_term/payment_term_state.dart';
import 'package:invoiceninja_flutter/data/models/design_model.dart';
import 'package:invoiceninja_flutter/redux/design/design_state.dart';
import 'package:invoiceninja_flutter/redux/credit/credit_state.dart';
@ -110,6 +113,9 @@ part 'serializers.g.dart';
TaxRateItemResponse,
TaxRateListResponse,
// STARTER: serializers - do not remove comment
PaymentTermEntity,
PaymentTermListResponse,
PaymentTermItemResponse,
DesignEntity,
DesignListResponse,
DesignItemResponse,

View File

@ -100,6 +100,10 @@ Serializers _$serializers = (new Serializers().toBuilder()
..add(PaymentListResponse.serializer)
..add(PaymentState.serializer)
..add(PaymentTermEntity.serializer)
..add(PaymentTermItemResponse.serializer)
..add(PaymentTermListResponse.serializer)
..add(PaymentTermState.serializer)
..add(PaymentTermUIState.serializer)
..add(PaymentTypeEntity.serializer)
..add(PaymentTypeItemResponse.serializer)
..add(PaymentTypeListResponse.serializer)
@ -356,6 +360,7 @@ Serializers _$serializers = (new Serializers().toBuilder()
..addBuilderFactory(
const FullType(BuiltList, const [const FullType(LanguageEntity)]), () => new ListBuilder<LanguageEntity>())
..addBuilderFactory(const FullType(BuiltList, const [const FullType(PaymentEntity)]), () => new ListBuilder<PaymentEntity>())
..addBuilderFactory(const FullType(BuiltList, const [const FullType(PaymentTermEntity)]), () => new ListBuilder<PaymentTermEntity>())
..addBuilderFactory(const FullType(BuiltList, const [const FullType(PaymentTypeEntity)]), () => new ListBuilder<PaymentTypeEntity>())
..addBuilderFactory(const FullType(BuiltList, const [const FullType(PaymentableEntity)]), () => new ListBuilder<PaymentableEntity>())
..addBuilderFactory(const FullType(BuiltList, const [const FullType(PaymentableEntity)]), () => new ListBuilder<PaymentableEntity>())
@ -416,6 +421,8 @@ 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(PaymentEntity)]), () => new MapBuilder<String, PaymentEntity>())
..addBuilderFactory(const FullType(BuiltList, const [const FullType(String)]), () => new ListBuilder<String>())
..addBuilderFactory(const FullType(BuiltMap, const [const FullType(String), const FullType(PaymentTermEntity)]), () => new MapBuilder<String, PaymentTermEntity>())
..addBuilderFactory(const FullType(BuiltList, const [const FullType(String)]), () => new ListBuilder<String>())
..addBuilderFactory(const FullType(BuiltMap, const [const FullType(String), const FullType(ProductEntity)]), () => new MapBuilder<String, ProductEntity>())
..addBuilderFactory(const FullType(BuiltList, const [const FullType(String)]), () => new ListBuilder<String>())
..addBuilderFactory(const FullType(BuiltMap, const [const FullType(String), const FullType(ProjectEntity)]), () => new MapBuilder<String, ProjectEntity>())

View File

@ -0,0 +1,79 @@
import 'dart:async';
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/payment_term_model.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 PaymentTermRepository {
const PaymentTermRepository({
this.webClient = const WebClient(),
});
final WebClient webClient;
Future<PaymentTermEntity> loadItem(
Credentials credentials, String entityId) async {
final dynamic response = await webClient.get(
'${credentials.url}/payment_terms/$entityId', credentials.token);
final PaymentTermItemResponse paymentTermResponse = serializers
.deserializeWith(PaymentTermItemResponse.serializer, response);
return paymentTermResponse.data;
}
Future<BuiltList<PaymentTermEntity>> loadList(
Credentials credentials, int updatedAt) async {
String url = credentials.url + '/payment_terms?';
if (updatedAt > 0) {
url += '&updated_at=${updatedAt - kUpdatedAtBufferSeconds}';
}
final dynamic response = await webClient.get(url, credentials.token);
final PaymentTermListResponse paymentTermResponse = serializers
.deserializeWith(PaymentTermListResponse.serializer, response);
return paymentTermResponse.data;
}
Future<List<PaymentTermEntity>> bulkAction(
Credentials credentials, List<String> ids, EntityAction action) async {
final url = credentials.url + '/payment_terms/bulk';
final dynamic response = await webClient.post(url, credentials.token,
data: json.encode({'ids': ids, 'action': '$action'}));
final PaymentTermListResponse paymentTermResponse = serializers
.deserializeWith(PaymentTermListResponse.serializer, response);
return paymentTermResponse.data.toList();
}
Future<PaymentTermEntity> saveData(
Credentials credentials, PaymentTermEntity paymentTerm) async {
final data =
serializers.serializeWith(PaymentTermEntity.serializer, paymentTerm);
dynamic response;
if (paymentTerm.isNew) {
response = await webClient.post(
credentials.url + '/payment_terms', credentials.token,
data: json.encode(data));
} else {
final url = '${credentials.url}/payment_terms/${paymentTerm.id}';
response =
await webClient.put(url, credentials.token, data: json.encode(data));
}
final PaymentTermItemResponse paymentTermResponse = serializers
.deserializeWith(PaymentTermItemResponse.serializer, response);
return paymentTermResponse.data;
}
}

View File

@ -39,6 +39,7 @@ import 'package:shared_preferences/shared_preferences.dart';
import 'package:invoiceninja_flutter/utils/web_stub.dart'
if (dart.library.html) 'package:invoiceninja_flutter/utils/web.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/redux/payment_term/payment_term_middleware.dart';
void main({bool isTesting = false}) async {
WidgetsFlutterBinding.ensureInitialized();
@ -68,6 +69,7 @@ void main({bool isTesting = false}) async {
..addAll(createStoreSettingsMiddleware())
..addAll(createStoreReportsMiddleware())
// STARTER: middleware - do not remove comment
..addAll(createStorePaymentTermsMiddleware())
..addAll(createStoreDesignsMiddleware())
..addAll(createStoreCreditsMiddleware())
..addAll(createStoreUsersMiddleware())

View File

@ -27,6 +27,10 @@ import 'package:invoiceninja_flutter/ui/design/design_screen_vm.dart';
import 'package:invoiceninja_flutter/ui/design/edit/design_edit_vm.dart';
import 'package:invoiceninja_flutter/ui/design/view/design_view_vm.dart';
import 'package:invoiceninja_flutter/ui/payment/refund/payment_refund_vm.dart';
import 'package:invoiceninja_flutter/ui/payment_term/edit/payment_term_edit_vm.dart';
import 'package:invoiceninja_flutter/ui/payment_term/payment_term_screen.dart';
import 'package:invoiceninja_flutter/ui/payment_term/payment_term_screen_vm.dart';
import 'package:invoiceninja_flutter/ui/payment_term/view/payment_term_view_vm.dart';
import 'package:invoiceninja_flutter/ui/reports/reports_screen.dart';
import 'package:invoiceninja_flutter/ui/reports/reports_screen_vm.dart';
import 'package:invoiceninja_flutter/ui/settings/account_management_vm.dart';
@ -221,6 +225,12 @@ class InvoiceNinjaAppState extends State<InvoiceNinjaApp> {
QuoteEditScreen.route: (context) => QuoteEditScreen(),
QuoteEmailScreen.route: (context) => QuoteEmailScreen(),
// STARTER: routes - do not remove comment
PaymentTermScreen.route: (context) =>
PaymentTermScreenBuilder(),
PaymentTermViewScreen.route: (context) =>
PaymentTermViewScreen(),
PaymentTermEditScreen.route: (context) =>
PaymentTermEditScreen(),
DesignScreen.route: (context) => DesignScreenBuilder(),
DesignViewScreen.route: (context) => DesignViewScreen(),
DesignEditScreen.route: (context) => DesignEditScreen(),

View File

@ -7,6 +7,7 @@ import 'package:invoiceninja_flutter/data/models/company_gateway_model.dart';
import 'package:invoiceninja_flutter/data/models/entities.dart';
import 'package:invoiceninja_flutter/data/models/group_model.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/data/models/payment_term_model.dart';
import 'package:invoiceninja_flutter/data/models/static/static_data_model.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/client/client_actions.dart';
@ -30,6 +31,7 @@ import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/utils/dialogs.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/redux/payment_term/payment_term_actions.dart';
class PersistUI {}
@ -245,6 +247,13 @@ void filterEntitiesByType({
));
break;
// STARTER: filter - do not remove comment
case EntityType.paymentTerm:
store.dispatch(FilterPaymentTermsByEntity(
entityId: filterEntity.id,
entityType: filterEntity.entityType,
));
break;
case EntityType.design:
store.dispatch(FilterDesignsByEntity(
entityId: filterEntity.id,
@ -319,6 +328,10 @@ void viewEntitiesByType({
action = ViewGroupList(navigator: navigator);
break;
// STARTER: view list - do not remove comment
case EntityType.paymentTerm:
store.dispatch(ViewPaymentTermList(navigator: navigator));
break;
case EntityType.design:
action = ViewDesignList(navigator: navigator);
break;
@ -456,6 +469,14 @@ void viewEntityById({
));
break;
// STARTER: view - do not remove comment
case EntityType.paymentTerm:
store.dispatch(ViewPaymentTerm(
paymentTermId: entityId,
navigator: navigator,
force: force,
));
break;
case EntityType.design:
store.dispatch(ViewDesign(
designId: entityId,
@ -587,6 +608,14 @@ void createEntityByType(
));
break;
// STARTER: create type - do not remove comment
case EntityType.paymentTerm:
store.dispatch(EditPaymentTerm(
navigator: navigator,
force: force,
paymentTerm: PaymentTermEntity(state: state),
));
break;
case EntityType.design:
store.dispatch(EditDesign(
navigator: navigator,
@ -736,6 +765,15 @@ void createEntity({
));
break;
// STARTER: create - do not remove comment
case EntityType.paymentTerm:
store.dispatch(EditPaymentTerm(
navigator: navigator,
paymentTerm: entity,
force: force,
completer: completer,
));
break;
case EntityType.design:
store.dispatch(EditDesign(
navigator: navigator,
@ -935,6 +973,19 @@ void editEntityById(
));
break;
// STARTER: edit - do not remove comment
case EntityType.paymentTerm:
store.dispatch(EditPaymentTerm(
paymentTerm: map[entityId],
navigator: navigator,
completer: completer ??
snackBarCompleter<PaymentTermEntity>(
context,
entity.isNew
? localization.createdPaymentTerm
: localization.updatedPaymentTerm),
));
break;
case EntityType.design:
store.dispatch(EditDesign(
design: map[entityId],
@ -1030,6 +1081,10 @@ void handleEntitiesActions(
handleDocumentAction(context, entities, action);
break;
// STARTER: actions - do not remove comment
case EntityType.paymentTerm:
handlePaymentTermAction(context, entities, action);
break;
case EntityType.design:
handleDesignAction(context, entities, action);
break;

View File

@ -18,6 +18,8 @@ import 'package:invoiceninja_flutter/redux/auth/auth_reducer.dart';
import 'package:invoiceninja_flutter/redux/company/company_reducer.dart';
import 'package:invoiceninja_flutter/redux/static/static_reducer.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/redux/payment_term/payment_term_actions.dart';
import 'package:invoiceninja_flutter/redux/design/design_actions.dart';
import 'package:invoiceninja_flutter/redux/credit/credit_actions.dart';
@ -81,6 +83,10 @@ final lastErrorReducer = combineReducers<String>([
return '${action.error}';
}),
// STARTER: errors - do not remove comment
TypedReducer<String, LoadPaymentTermsFailure>((state, action) {
return '${action.error}';
}),
TypedReducer<String, LoadDesignsFailure>((state, action) {
return '${action.error}';
}),

View File

@ -47,6 +47,12 @@ import 'package:invoiceninja_flutter/ui/group/edit/group_edit_vm.dart';
import 'package:invoiceninja_flutter/ui/product/edit/product_edit_vm.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/redux/payment_term/payment_term_state.dart';
import 'package:invoiceninja_flutter/ui/payment_term/edit/payment_term_edit_vm.dart';
import 'package:invoiceninja_flutter/redux/payment_term/payment_term_state.dart';
import 'package:invoiceninja_flutter/ui/payment_term/edit/payment_term_edit_vm.dart';
import 'package:invoiceninja_flutter/redux/payment_term/payment_term_selectors.dart';
import 'package:invoiceninja_flutter/redux/credit/credit_state.dart';
import 'package:invoiceninja_flutter/redux/user/user_state.dart';
@ -185,6 +191,9 @@ abstract class AppState implements Built<AppState, AppStateBuilder> {
case EntityType.invoice:
return invoiceState.map;
// STARTER: states switch map - do not remove comment
case EntityType.paymentTerm:
return paymentTermState.map;
case EntityType.design:
return designState.map;
@ -248,6 +257,9 @@ abstract class AppState implements Built<AppState, AppStateBuilder> {
case EntityType.invoice:
return invoiceState.list;
// STARTER: states switch list - do not remove comment
case EntityType.paymentTerm:
return paymentTermState.list;
case EntityType.design:
return designState.list;
@ -290,6 +302,9 @@ abstract class AppState implements Built<AppState, AppStateBuilder> {
case EntityType.invoice:
return invoiceUIState;
// STARTER: states switch - do not remove comment
case EntityType.paymentTerm:
return paymentTermUIState;
case EntityType.design:
return designUIState;
case EntityType.credit:
@ -344,6 +359,11 @@ abstract class AppState implements Built<AppState, AppStateBuilder> {
ListUIState get invoiceListState => uiState.invoiceUIState.listUIState;
// STARTER: state getters - do not remove comment
PaymentTermState get paymentTermState => userCompanyState.paymentTermState;
ListUIState get paymentTermListState =>
uiState.paymentTermUIState.listUIState;
PaymentTermUIState get paymentTermUIState => uiState.paymentTermUIState;
DesignState get designState => userCompanyState.designState;
ListUIState get designListState => uiState.designUIState.listUIState;
@ -457,6 +477,10 @@ abstract class AppState implements Built<AppState, AppStateBuilder> {
case CreditEditScreen.route:
return hasCreditChanges(creditUIState.editing, creditState.map);
// STARTER: has changes - do not remove comment
case PaymentTermEditScreen.route:
return hasPaymentTermChanges(
paymentTermUIState.editing, paymentTermState.map);
case DesignEditScreen.route:
return hasDesignChanges(designUIState.editing, designState.map);
}

View File

@ -18,6 +18,8 @@ import 'package:invoiceninja_flutter/redux/payment/payment_reducer.dart';
import 'package:invoiceninja_flutter/redux/quote/quote_reducer.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/redux/payment_term/payment_term_reducer.dart';
import 'package:invoiceninja_flutter/redux/design/design_reducer.dart';
import 'package:invoiceninja_flutter/redux/credit/credit_reducer.dart';
@ -42,6 +44,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
..paymentTermState
.replace(paymentTermsReducer(state.paymentTermState, action))
..designState.replace(designsReducer(state.designState, action))
..creditState.replace(creditsReducer(state.creditState, action))
..userState.replace(usersReducer(state.userState, action))

View File

@ -7,6 +7,8 @@ import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:built_value/built_value.dart';
import 'package:built_value/serializer.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/redux/payment_term/payment_term_state.dart';
import 'package:invoiceninja_flutter/redux/design/design_state.dart';
import 'package:invoiceninja_flutter/redux/credit/credit_state.dart';
@ -41,6 +43,8 @@ abstract class UserCompanyState
paymentState: PaymentState(),
quoteState: QuoteState(),
// STARTER: constructor - do not remove comment
paymentTermState: PaymentTermState(),
designState: DesignState(),
creditState: CreditState(),
@ -82,6 +86,8 @@ abstract class UserCompanyState
QuoteState get quoteState;
// STARTER: fields - do not remove comment
PaymentTermState get paymentTermState;
DesignState get designState;
CreditState get creditState;

View File

@ -52,6 +52,9 @@ class _$UserCompanyStateSerializer
'quoteState',
serializers.serialize(object.quoteState,
specifiedType: const FullType(QuoteState)),
'paymentTermState',
serializers.serialize(object.paymentTermState,
specifiedType: const FullType(PaymentTermState)),
'designState',
serializers.serialize(object.designState,
specifiedType: const FullType(DesignState)),
@ -137,6 +140,11 @@ class _$UserCompanyStateSerializer
result.quoteState.replace(serializers.deserialize(value,
specifiedType: const FullType(QuoteState)) as QuoteState);
break;
case 'paymentTermState':
result.paymentTermState.replace(serializers.deserialize(value,
specifiedType: const FullType(PaymentTermState))
as PaymentTermState);
break;
case 'designState':
result.designState.replace(serializers.deserialize(value,
specifiedType: const FullType(DesignState)) as DesignState);
@ -328,6 +336,8 @@ class _$UserCompanyState extends UserCompanyState {
@override
final QuoteState quoteState;
@override
final PaymentTermState paymentTermState;
@override
final DesignState designState;
@override
final CreditState creditState;
@ -356,6 +366,7 @@ class _$UserCompanyState extends UserCompanyState {
this.projectState,
this.paymentState,
this.quoteState,
this.paymentTermState,
this.designState,
this.creditState,
this.userState,
@ -393,6 +404,10 @@ class _$UserCompanyState extends UserCompanyState {
if (quoteState == null) {
throw new BuiltValueNullFieldError('UserCompanyState', 'quoteState');
}
if (paymentTermState == null) {
throw new BuiltValueNullFieldError(
'UserCompanyState', 'paymentTermState');
}
if (designState == null) {
throw new BuiltValueNullFieldError('UserCompanyState', 'designState');
}
@ -437,6 +452,7 @@ class _$UserCompanyState extends UserCompanyState {
projectState == other.projectState &&
paymentState == other.paymentState &&
quoteState == other.quoteState &&
paymentTermState == other.paymentTermState &&
designState == other.designState &&
creditState == other.creditState &&
userState == other.userState &&
@ -465,22 +481,25 @@ class _$UserCompanyState extends UserCompanyState {
$jc(
$jc(
$jc(
0,
userCompany
$jc(
0,
userCompany
.hashCode),
documentState
.hashCode),
documentState
productState
.hashCode),
productState
clientState
.hashCode),
clientState
invoiceState
.hashCode),
invoiceState.hashCode),
expenseState.hashCode),
vendorState.hashCode),
taskState.hashCode),
projectState.hashCode),
paymentState.hashCode),
quoteState.hashCode),
expenseState.hashCode),
vendorState.hashCode),
taskState.hashCode),
projectState.hashCode),
paymentState.hashCode),
quoteState.hashCode),
paymentTermState.hashCode),
designState.hashCode),
creditState.hashCode),
userState.hashCode),
@ -503,6 +522,7 @@ class _$UserCompanyState extends UserCompanyState {
..add('projectState', projectState)
..add('paymentState', paymentState)
..add('quoteState', quoteState)
..add('paymentTermState', paymentTermState)
..add('designState', designState)
..add('creditState', creditState)
..add('userState', userState)
@ -582,6 +602,12 @@ class UserCompanyStateBuilder
set quoteState(QuoteStateBuilder quoteState) =>
_$this._quoteState = quoteState;
PaymentTermStateBuilder _paymentTermState;
PaymentTermStateBuilder get paymentTermState =>
_$this._paymentTermState ??= new PaymentTermStateBuilder();
set paymentTermState(PaymentTermStateBuilder paymentTermState) =>
_$this._paymentTermState = paymentTermState;
DesignStateBuilder _designState;
DesignStateBuilder get designState =>
_$this._designState ??= new DesignStateBuilder();
@ -632,6 +658,7 @@ class UserCompanyStateBuilder
_projectState = _$v.projectState?.toBuilder();
_paymentState = _$v.paymentState?.toBuilder();
_quoteState = _$v.quoteState?.toBuilder();
_paymentTermState = _$v.paymentTermState?.toBuilder();
_designState = _$v.designState?.toBuilder();
_creditState = _$v.creditState?.toBuilder();
_userState = _$v.userState?.toBuilder();
@ -673,6 +700,7 @@ class UserCompanyStateBuilder
projectState: projectState.build(),
paymentState: paymentState.build(),
quoteState: quoteState.build(),
paymentTermState: paymentTermState.build(),
designState: designState.build(),
creditState: creditState.build(),
userState: userState.build(),
@ -704,6 +732,8 @@ class UserCompanyStateBuilder
paymentState.build();
_$failedField = 'quoteState';
quoteState.build();
_$failedField = 'paymentTermState';
paymentTermState.build();
_$failedField = 'designState';
designState.build();
_$failedField = 'creditState';

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/data/models/payment_term_model.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';
class ViewPaymentTermList extends AbstractNavigatorAction
implements PersistUI, StopLoading {
ViewPaymentTermList({
@required NavigatorState navigator,
this.force = false,
}) : super(navigator: navigator);
final bool force;
}
class ViewPaymentTerm extends AbstractNavigatorAction
implements PersistUI, PersistPrefs {
ViewPaymentTerm({
@required NavigatorState navigator,
@required this.paymentTermId,
this.force = false,
}) : super(navigator: navigator);
final String paymentTermId;
final bool force;
}
class EditPaymentTerm extends AbstractNavigatorAction
implements PersistUI, PersistPrefs {
EditPaymentTerm(
{@required this.paymentTerm,
@required NavigatorState navigator,
this.completer,
this.cancelCompleter,
this.force = false})
: super(navigator: navigator);
final PaymentTermEntity paymentTerm;
final Completer completer;
final Completer cancelCompleter;
final bool force;
}
class UpdatePaymentTerm implements PersistUI {
UpdatePaymentTerm(this.paymentTerm);
final PaymentTermEntity paymentTerm;
}
class LoadPaymentTerm {
LoadPaymentTerm({this.completer, this.paymentTermId});
final Completer completer;
final String paymentTermId;
}
class LoadPaymentTermActivity {
LoadPaymentTermActivity({this.completer, this.paymentTermId});
final Completer completer;
final String paymentTermId;
}
class LoadPaymentTerms {
LoadPaymentTerms({this.completer, this.force = false});
final Completer completer;
final bool force;
}
class LoadPaymentTermRequest implements StartLoading {}
class LoadPaymentTermFailure implements StopLoading {
LoadPaymentTermFailure(this.error);
final dynamic error;
@override
String toString() {
return 'LoadPaymentTermFailure{error: $error}';
}
}
class LoadPaymentTermSuccess implements StopLoading, PersistData {
LoadPaymentTermSuccess(this.paymentTerm);
final PaymentTermEntity paymentTerm;
@override
String toString() {
return 'LoadPaymentTermSuccess{paymentTerm: $paymentTerm}';
}
}
class LoadPaymentTermsRequest implements StartLoading {}
class LoadPaymentTermsFailure implements StopLoading {
LoadPaymentTermsFailure(this.error);
final dynamic error;
@override
String toString() {
return 'LoadPaymentTermsFailure{error: $error}';
}
}
class LoadPaymentTermsSuccess implements StopLoading, PersistData {
LoadPaymentTermsSuccess(this.paymentTerms);
final BuiltList<PaymentTermEntity> paymentTerms;
@override
String toString() {
return 'LoadPaymentTermsSuccess{paymentTerms: $paymentTerms}';
}
}
class SavePaymentTermRequest implements StartSaving {
SavePaymentTermRequest({this.completer, this.paymentTerm});
final Completer completer;
final PaymentTermEntity paymentTerm;
}
class SavePaymentTermSuccess implements StopSaving, PersistData, PersistUI {
SavePaymentTermSuccess(this.paymentTerm);
final PaymentTermEntity paymentTerm;
}
class AddPaymentTermSuccess implements StopSaving, PersistData, PersistUI {
AddPaymentTermSuccess(this.paymentTerm);
final PaymentTermEntity paymentTerm;
}
class SavePaymentTermFailure implements StopSaving {
SavePaymentTermFailure(this.error);
final Object error;
}
class ArchivePaymentTermsRequest implements StartSaving {
ArchivePaymentTermsRequest(this.completer, this.paymentTermIds);
final Completer completer;
final List<String> paymentTermIds;
}
class ArchivePaymentTermsSuccess implements StopSaving, PersistData {
ArchivePaymentTermsSuccess(this.paymentTerms);
final List<PaymentTermEntity> paymentTerms;
}
class ArchivePaymentTermsFailure implements StopSaving {
ArchivePaymentTermsFailure(this.paymentTerms);
final List<PaymentTermEntity> paymentTerms;
}
class DeletePaymentTermsRequest implements StartSaving {
DeletePaymentTermsRequest(this.completer, this.paymentTermIds);
final Completer completer;
final List<String> paymentTermIds;
}
class DeletePaymentTermsSuccess implements StopSaving, PersistData {
DeletePaymentTermsSuccess(this.paymentTerms);
final List<PaymentTermEntity> paymentTerms;
}
class DeletePaymentTermsFailure implements StopSaving {
DeletePaymentTermsFailure(this.paymentTerms);
final List<PaymentTermEntity> paymentTerms;
}
class RestorePaymentTermsRequest implements StartSaving {
RestorePaymentTermsRequest(this.completer, this.paymentTermIds);
final Completer completer;
final List<String> paymentTermIds;
}
class RestorePaymentTermsSuccess implements StopSaving, PersistData {
RestorePaymentTermsSuccess(this.paymentTerms);
final List<PaymentTermEntity> paymentTerms;
}
class RestorePaymentTermsFailure implements StopSaving {
RestorePaymentTermsFailure(this.paymentTerms);
final List<PaymentTermEntity> paymentTerms;
}
class FilterPaymentTerms implements PersistUI {
FilterPaymentTerms(this.filter);
final String filter;
}
class SortPaymentTerms implements PersistUI {
SortPaymentTerms(this.field);
final String field;
}
class FilterPaymentTermsByState implements PersistUI {
FilterPaymentTermsByState(this.state);
final EntityState state;
}
class FilterPaymentTermsByCustom1 implements PersistUI {
FilterPaymentTermsByCustom1(this.value);
final String value;
}
class FilterPaymentTermsByCustom2 implements PersistUI {
FilterPaymentTermsByCustom2(this.value);
final String value;
}
class FilterPaymentTermsByCustom3 implements PersistUI {
FilterPaymentTermsByCustom3(this.value);
final String value;
}
class FilterPaymentTermsByCustom4 implements PersistUI {
FilterPaymentTermsByCustom4(this.value);
final String value;
}
class FilterPaymentTermsByEntity implements PersistUI {
FilterPaymentTermsByEntity({this.entityId, this.entityType});
final String entityId;
final EntityType entityType;
}
void handlePaymentTermAction(
BuildContext context, List<BaseEntity> paymentTerms, EntityAction action) {
if (paymentTerms.isEmpty) {
return;
}
final store = StoreProvider.of<AppState>(context);
final state = store.state;
final CompanyEntity company = state.company;
final localization = AppLocalization.of(context);
final paymentTerm = paymentTerms.first as PaymentTermEntity;
final paymentTermIds =
paymentTerms.map((paymentTerm) => paymentTerm.id).toList();
switch (action) {
case EntityAction.edit:
editEntity(context: context, entity: paymentTerm);
break;
case EntityAction.restore:
store.dispatch(RestorePaymentTermsRequest(
snackBarCompleter<Null>(context, localization.restoredPaymentTerm),
paymentTermIds));
break;
case EntityAction.archive:
store.dispatch(ArchivePaymentTermsRequest(
snackBarCompleter<Null>(context, localization.archivedPaymentTerm),
paymentTermIds));
break;
case EntityAction.delete:
store.dispatch(DeletePaymentTermsRequest(
snackBarCompleter<Null>(context, localization.deletedPaymentTerm),
paymentTermIds));
break;
case EntityAction.toggleMultiselect:
if (!store.state.paymentTermListState.isInMultiselect()) {
store.dispatch(StartPaymentTermMultiselect());
}
if (paymentTerms.isEmpty) {
break;
}
for (final paymentTerm in paymentTerms) {
if (!store.state.paymentTermListState.isSelected(paymentTerm.id)) {
store.dispatch(AddToPaymentTermMultiselect(entity: paymentTerm));
} else {
store.dispatch(RemoveFromPaymentTermMultiselect(entity: paymentTerm));
}
}
break;
}
}
class StartPaymentTermMultiselect {
StartPaymentTermMultiselect();
}
class AddToPaymentTermMultiselect {
AddToPaymentTermMultiselect({@required this.entity});
final BaseEntity entity;
}
class RemoveFromPaymentTermMultiselect {
RemoveFromPaymentTermMultiselect({@required this.entity});
final BaseEntity entity;
}
class ClearPaymentTermMultiselect {
ClearPaymentTermMultiselect();
}

View File

@ -0,0 +1,281 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:invoiceninja_flutter/data/models/payment_term_model.dart';
import 'package:redux/redux.dart';
import 'package:invoiceninja_flutter/utils/platforms.dart';
import 'package:invoiceninja_flutter/redux/app/app_middleware.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/ui/ui_actions.dart';
import 'package:invoiceninja_flutter/ui/payment_term/payment_term_screen.dart';
import 'package:invoiceninja_flutter/ui/payment_term/edit/payment_term_edit_vm.dart';
import 'package:invoiceninja_flutter/ui/payment_term/view/payment_term_view_vm.dart';
import 'package:invoiceninja_flutter/redux/payment_term/payment_term_actions.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/data/repositories/payment_term_repository.dart';
List<Middleware<AppState>> createStorePaymentTermsMiddleware([
PaymentTermRepository repository = const PaymentTermRepository(),
]) {
final viewPaymentTermList = _viewPaymentTermList();
final viewPaymentTerm = _viewPaymentTerm();
final editPaymentTerm = _editPaymentTerm();
final loadPaymentTerms = _loadPaymentTerms(repository);
final loadPaymentTerm = _loadPaymentTerm(repository);
final savePaymentTerm = _savePaymentTerm(repository);
final archivePaymentTerm = _archivePaymentTerm(repository);
final deletePaymentTerm = _deletePaymentTerm(repository);
final restorePaymentTerm = _restorePaymentTerm(repository);
return [
TypedMiddleware<AppState, ViewPaymentTermList>(viewPaymentTermList),
TypedMiddleware<AppState, ViewPaymentTerm>(viewPaymentTerm),
TypedMiddleware<AppState, EditPaymentTerm>(editPaymentTerm),
TypedMiddleware<AppState, LoadPaymentTerms>(loadPaymentTerms),
TypedMiddleware<AppState, LoadPaymentTerm>(loadPaymentTerm),
TypedMiddleware<AppState, SavePaymentTermRequest>(savePaymentTerm),
TypedMiddleware<AppState, ArchivePaymentTermsRequest>(archivePaymentTerm),
TypedMiddleware<AppState, DeletePaymentTermsRequest>(deletePaymentTerm),
TypedMiddleware<AppState, RestorePaymentTermsRequest>(restorePaymentTerm),
];
}
Middleware<AppState> _editPaymentTerm() {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as EditPaymentTerm;
if (!action.force &&
hasChanges(store: store, context: action.context, action: action)) {
return;
}
next(action);
store.dispatch(UpdateCurrentRoute(PaymentTermEditScreen.route));
if (isMobile(action.context)) {
action.navigator.pushNamed(PaymentTermEditScreen.route);
}
};
}
Middleware<AppState> _viewPaymentTerm() {
return (Store<AppState> store, dynamic dynamicAction,
NextDispatcher next) async {
final action = dynamicAction as ViewPaymentTerm;
if (!action.force &&
hasChanges(store: store, context: action.context, action: action)) {
return;
}
next(action);
store.dispatch(UpdateCurrentRoute(PaymentTermViewScreen.route));
if (isMobile(action.context)) {
Navigator.of(action.context).pushNamed(PaymentTermViewScreen.route);
}
};
}
Middleware<AppState> _viewPaymentTermList() {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as ViewPaymentTermList;
if (!action.force &&
hasChanges(store: store, context: action.context, action: action)) {
return;
}
next(action);
if (store.state.paymentTermState.isStale) {
store.dispatch(LoadPaymentTerms());
}
store.dispatch(UpdateCurrentRoute(PaymentTermScreen.route));
if (isMobile(action.context)) {
Navigator.of(action.context).pushNamedAndRemoveUntil(
PaymentTermScreen.route, (Route<dynamic> route) => false);
}
};
}
Middleware<AppState> _archivePaymentTerm(PaymentTermRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as ArchivePaymentTermsRequest;
final prevPaymentTerms = action.paymentTermIds
.map((id) => store.state.paymentTermState.map[id])
.toList();
repository
.bulkAction(store.state.credentials, action.paymentTermIds,
EntityAction.archive)
.then((List<PaymentTermEntity> paymentTerms) {
store.dispatch(ArchivePaymentTermsSuccess(paymentTerms));
if (action.completer != null) {
action.completer.complete(null);
}
}).catchError((Object error) {
print(error);
store.dispatch(ArchivePaymentTermsFailure(prevPaymentTerms));
if (action.completer != null) {
action.completer.completeError(error);
}
});
next(action);
};
}
Middleware<AppState> _deletePaymentTerm(PaymentTermRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as DeletePaymentTermsRequest;
final prevPaymentTerms = action.paymentTermIds
.map((id) => store.state.paymentTermState.map[id])
.toList();
repository
.bulkAction(
store.state.credentials, action.paymentTermIds, EntityAction.delete)
.then((List<PaymentTermEntity> paymentTerms) {
store.dispatch(DeletePaymentTermsSuccess(paymentTerms));
if (action.completer != null) {
action.completer.complete(null);
}
}).catchError((Object error) {
print(error);
store.dispatch(DeletePaymentTermsFailure(prevPaymentTerms));
if (action.completer != null) {
action.completer.completeError(error);
}
});
next(action);
};
}
Middleware<AppState> _restorePaymentTerm(PaymentTermRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as RestorePaymentTermsRequest;
final prevPaymentTerms = action.paymentTermIds
.map((id) => store.state.paymentTermState.map[id])
.toList();
repository
.bulkAction(store.state.credentials, action.paymentTermIds,
EntityAction.restore)
.then((List<PaymentTermEntity> paymentTerms) {
store.dispatch(RestorePaymentTermsSuccess(paymentTerms));
if (action.completer != null) {
action.completer.complete(null);
}
}).catchError((Object error) {
print(error);
store.dispatch(RestorePaymentTermsFailure(prevPaymentTerms));
if (action.completer != null) {
action.completer.completeError(error);
}
});
next(action);
};
}
Middleware<AppState> _savePaymentTerm(PaymentTermRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as SavePaymentTermRequest;
repository
.saveData(store.state.credentials, action.paymentTerm)
.then((PaymentTermEntity paymentTerm) {
if (action.paymentTerm.isNew) {
store.dispatch(AddPaymentTermSuccess(paymentTerm));
} else {
store.dispatch(SavePaymentTermSuccess(paymentTerm));
}
action.completer.complete(paymentTerm);
final paymentTermUIState = store.state.paymentTermUIState;
if (paymentTermUIState.saveCompleter != null) {
paymentTermUIState.saveCompleter.complete(paymentTerm);
}
}).catchError((Object error) {
print(error);
store.dispatch(SavePaymentTermFailure(error));
action.completer.completeError(error);
});
next(action);
};
}
Middleware<AppState> _loadPaymentTerm(PaymentTermRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as LoadPaymentTerm;
final AppState state = store.state;
if (state.isLoading) {
next(action);
return;
}
store.dispatch(LoadPaymentTermRequest());
repository
.loadItem(state.credentials, action.paymentTermId)
.then((paymentTerm) {
store.dispatch(LoadPaymentTermSuccess(paymentTerm));
if (action.completer != null) {
action.completer.complete(null);
}
}).catchError((Object error) {
print(error);
store.dispatch(LoadPaymentTermFailure(error));
if (action.completer != null) {
action.completer.completeError(error);
}
});
next(action);
};
}
Middleware<AppState> _loadPaymentTerms(PaymentTermRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as LoadPaymentTerms;
final AppState state = store.state;
if (!state.paymentTermState.isStale && !action.force) {
next(action);
return;
}
if (state.isLoading) {
next(action);
return;
}
final int updatedAt = (state.paymentTermState.lastUpdated / 1000).round();
store.dispatch(LoadPaymentTermsRequest());
repository.loadList(state.credentials, updatedAt).then((data) {
store.dispatch(LoadPaymentTermsSuccess(data));
if (action.completer != null) {
action.completer.complete(null);
}
/*
if (state.productState.isStale) {
store.dispatch(LoadProducts());
}
*/
}).catchError((Object error) {
print(error);
store.dispatch(LoadPaymentTermsFailure(error));
if (action.completer != null) {
action.completer.completeError(error);
}
});
next(action);
};
}

View File

@ -0,0 +1,308 @@
import 'package:invoiceninja_flutter/data/models/payment_term_model.dart';
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/redux/company/company_actions.dart';
import 'package:invoiceninja_flutter/redux/ui/entity_ui_state.dart';
import 'package:invoiceninja_flutter/redux/payment_term/payment_term_actions.dart';
import 'package:invoiceninja_flutter/redux/ui/list_ui_state.dart';
import 'package:invoiceninja_flutter/redux/payment_term/payment_term_state.dart';
EntityUIState paymentTermUIReducer(PaymentTermUIState state, dynamic action) {
return state.rebuild((b) => b
..listUIState.replace(paymentTermListReducer(state.listUIState, action))
..editing.replace(editingReducer(state.editing, action))
..selectedId = selectedIdReducer(state.selectedId, action));
}
Reducer<String> selectedIdReducer = combineReducers([
TypedReducer<String, ViewPaymentTerm>(
(String selectedId, dynamic action) => action.paymentTermId),
TypedReducer<String, AddPaymentTermSuccess>(
(String selectedId, dynamic action) => action.paymentTerm.id),
TypedReducer<String, SelectCompany>((selectedId, action) => ''),
]);
final editingReducer = combineReducers<PaymentTermEntity>([
TypedReducer<PaymentTermEntity, SavePaymentTermSuccess>(_updateEditing),
TypedReducer<PaymentTermEntity, AddPaymentTermSuccess>(_updateEditing),
TypedReducer<PaymentTermEntity, RestorePaymentTermsSuccess>(
(paymentTerms, action) {
return action.paymentTerms[0];
}),
TypedReducer<PaymentTermEntity, ArchivePaymentTermsSuccess>(
(paymentTerms, action) {
return action.paymentTerms[0];
}),
TypedReducer<PaymentTermEntity, DeletePaymentTermsSuccess>(
(paymentTerms, action) {
return action.paymentTerms[0];
}),
TypedReducer<PaymentTermEntity, EditPaymentTerm>(_updateEditing),
TypedReducer<PaymentTermEntity, UpdatePaymentTerm>((paymentTerm, action) {
return action.paymentTerm.rebuild((b) => b..isChanged = true);
}),
TypedReducer<PaymentTermEntity, SelectCompany>(_clearEditing),
TypedReducer<PaymentTermEntity, DiscardChanges>(_clearEditing),
]);
PaymentTermEntity _clearEditing(PaymentTermEntity paymentTerm, dynamic action) {
return PaymentTermEntity();
}
PaymentTermEntity _updateEditing(
PaymentTermEntity paymentTerm, dynamic action) {
return action.paymentTerm;
}
final paymentTermListReducer = combineReducers<ListUIState>([
TypedReducer<ListUIState, SortPaymentTerms>(_sortPaymentTerms),
TypedReducer<ListUIState, FilterPaymentTermsByState>(
_filterPaymentTermsByState),
TypedReducer<ListUIState, FilterPaymentTerms>(_filterPaymentTerms),
TypedReducer<ListUIState, FilterPaymentTermsByCustom1>(
_filterPaymentTermsByCustom1),
TypedReducer<ListUIState, FilterPaymentTermsByCustom2>(
_filterPaymentTermsByCustom2),
TypedReducer<ListUIState, FilterPaymentTermsByEntity>(
_filterPaymentTermsByClient),
TypedReducer<ListUIState, StartPaymentTermMultiselect>(_startListMultiselect),
TypedReducer<ListUIState, AddToPaymentTermMultiselect>(_addToListMultiselect),
TypedReducer<ListUIState, RemoveFromPaymentTermMultiselect>(
_removeFromListMultiselect),
TypedReducer<ListUIState, ClearPaymentTermMultiselect>(_clearListMultiselect),
TypedReducer<ListUIState, ClearEntityFilter>(
(state, action) => state.rebuild((b) => b
..filterEntityId = null
..filterEntityType = null)),
]);
ListUIState _filterPaymentTermsByClient(
ListUIState paymentTermListState, FilterPaymentTermsByEntity action) {
return paymentTermListState.rebuild((b) => b
..filterEntityId = action.entityId
..filterEntityType = action.entityType);
}
ListUIState _filterPaymentTermsByCustom1(
ListUIState paymentTermListState, FilterPaymentTermsByCustom1 action) {
if (paymentTermListState.custom1Filters.contains(action.value)) {
return paymentTermListState
.rebuild((b) => b..custom1Filters.remove(action.value));
} else {
return paymentTermListState
.rebuild((b) => b..custom1Filters.add(action.value));
}
}
ListUIState _filterPaymentTermsByCustom2(
ListUIState paymentTermListState, FilterPaymentTermsByCustom2 action) {
if (paymentTermListState.custom2Filters.contains(action.value)) {
return paymentTermListState
.rebuild((b) => b..custom2Filters.remove(action.value));
} else {
return paymentTermListState
.rebuild((b) => b..custom2Filters.add(action.value));
}
}
ListUIState _filterPaymentTermsByState(
ListUIState paymentTermListState, FilterPaymentTermsByState action) {
if (paymentTermListState.stateFilters.contains(action.state)) {
return paymentTermListState
.rebuild((b) => b..stateFilters.remove(action.state));
} else {
return paymentTermListState
.rebuild((b) => b..stateFilters.add(action.state));
}
}
ListUIState _filterPaymentTerms(
ListUIState paymentTermListState, FilterPaymentTerms action) {
return paymentTermListState.rebuild((b) => b
..filter = action.filter
..filterClearedAt = action.filter == null
? DateTime.now().millisecondsSinceEpoch
: paymentTermListState.filterClearedAt);
}
ListUIState _sortPaymentTerms(
ListUIState paymentTermListState, SortPaymentTerms action) {
return paymentTermListState.rebuild((b) => b
..sortAscending = b.sortField != action.field || !b.sortAscending
..sortField = action.field);
}
ListUIState _startListMultiselect(
ListUIState productListState, StartPaymentTermMultiselect action) {
return productListState.rebuild((b) => b..selectedIds = ListBuilder());
}
ListUIState _addToListMultiselect(
ListUIState productListState, AddToPaymentTermMultiselect action) {
return productListState.rebuild((b) => b..selectedIds.add(action.entity.id));
}
ListUIState _removeFromListMultiselect(
ListUIState productListState, RemoveFromPaymentTermMultiselect action) {
return productListState
.rebuild((b) => b..selectedIds.remove(action.entity.id));
}
ListUIState _clearListMultiselect(
ListUIState productListState, ClearPaymentTermMultiselect action) {
return productListState.rebuild((b) => b..selectedIds = null);
}
final paymentTermsReducer = combineReducers<PaymentTermState>([
TypedReducer<PaymentTermState, SavePaymentTermSuccess>(_updatePaymentTerm),
TypedReducer<PaymentTermState, AddPaymentTermSuccess>(_addPaymentTerm),
TypedReducer<PaymentTermState, LoadPaymentTermsSuccess>(
_setLoadedPaymentTerms),
TypedReducer<PaymentTermState, LoadPaymentTermSuccess>(_setLoadedPaymentTerm),
TypedReducer<PaymentTermState, ArchivePaymentTermsRequest>(
_archivePaymentTermRequest),
TypedReducer<PaymentTermState, ArchivePaymentTermsSuccess>(
_archivePaymentTermSuccess),
TypedReducer<PaymentTermState, ArchivePaymentTermsFailure>(
_archivePaymentTermFailure),
TypedReducer<PaymentTermState, DeletePaymentTermsRequest>(
_deletePaymentTermRequest),
TypedReducer<PaymentTermState, DeletePaymentTermsSuccess>(
_deletePaymentTermSuccess),
TypedReducer<PaymentTermState, DeletePaymentTermsFailure>(
_deletePaymentTermFailure),
TypedReducer<PaymentTermState, RestorePaymentTermsRequest>(
_restorePaymentTermRequest),
TypedReducer<PaymentTermState, RestorePaymentTermsSuccess>(
_restorePaymentTermSuccess),
TypedReducer<PaymentTermState, RestorePaymentTermsFailure>(
_restorePaymentTermFailure),
]);
PaymentTermState _archivePaymentTermRequest(
PaymentTermState paymentTermState, ArchivePaymentTermsRequest action) {
final paymentTerms =
action.paymentTermIds.map((id) => paymentTermState.map[id]).toList();
for (int i = 0; i < paymentTerms.length; i++) {
paymentTerms[i] = paymentTerms[i]
.rebuild((b) => b..archivedAt = DateTime.now().millisecondsSinceEpoch);
}
return paymentTermState.rebuild((b) {
for (final paymentTerm in paymentTerms) {
b.map[paymentTerm.id] = paymentTerm;
}
});
}
PaymentTermState _archivePaymentTermSuccess(
PaymentTermState paymentTermState, ArchivePaymentTermsSuccess action) {
return paymentTermState.rebuild((b) {
for (final paymentTerm in action.paymentTerms) {
b.map[paymentTerm.id] = paymentTerm;
}
});
}
PaymentTermState _archivePaymentTermFailure(
PaymentTermState paymentTermState, ArchivePaymentTermsFailure action) {
return paymentTermState.rebuild((b) {
for (final paymentTerm in action.paymentTerms) {
b.map[paymentTerm.id] = paymentTerm;
}
});
}
PaymentTermState _deletePaymentTermRequest(
PaymentTermState paymentTermState, DeletePaymentTermsRequest action) {
final paymentTerms =
action.paymentTermIds.map((id) => paymentTermState.map[id]).toList();
for (int i = 0; i < paymentTerms.length; i++) {
paymentTerms[i] = paymentTerms[i].rebuild((b) => b
..archivedAt = DateTime.now().millisecondsSinceEpoch
..isDeleted = true);
}
return paymentTermState.rebuild((b) {
for (final paymentTerm in paymentTerms) {
b.map[paymentTerm.id] = paymentTerm;
}
});
}
PaymentTermState _deletePaymentTermSuccess(
PaymentTermState paymentTermState, DeletePaymentTermsSuccess action) {
return paymentTermState.rebuild((b) {
for (final paymentTerm in action.paymentTerms) {
b.map[paymentTerm.id] = paymentTerm;
}
});
}
PaymentTermState _deletePaymentTermFailure(
PaymentTermState paymentTermState, DeletePaymentTermsFailure action) {
return paymentTermState.rebuild((b) {
for (final paymentTerm in action.paymentTerms) {
b.map[paymentTerm.id] = paymentTerm;
}
});
}
PaymentTermState _restorePaymentTermRequest(
PaymentTermState paymentTermState, RestorePaymentTermsRequest action) {
final paymentTerms =
action.paymentTermIds.map((id) => paymentTermState.map[id]).toList();
for (int i = 0; i < paymentTerms.length; i++) {
paymentTerms[i] = paymentTerms[i].rebuild((b) => b
..archivedAt = null
..isDeleted = false);
}
return paymentTermState.rebuild((b) {
for (final paymentTerm in paymentTerms) {
b.map[paymentTerm.id] = paymentTerm;
}
});
}
PaymentTermState _restorePaymentTermSuccess(
PaymentTermState paymentTermState, RestorePaymentTermsSuccess action) {
return paymentTermState.rebuild((b) {
for (final paymentTerm in action.paymentTerms) {
b.map[paymentTerm.id] = paymentTerm;
}
});
}
PaymentTermState _restorePaymentTermFailure(
PaymentTermState paymentTermState, RestorePaymentTermsFailure action) {
return paymentTermState.rebuild((b) {
for (final paymentTerm in action.paymentTerms) {
b.map[paymentTerm.id] = paymentTerm;
}
});
}
PaymentTermState _addPaymentTerm(
PaymentTermState paymentTermState, AddPaymentTermSuccess action) {
return paymentTermState.rebuild((b) => b
..map[action.paymentTerm.id] = action.paymentTerm
..list.add(action.paymentTerm.id));
}
PaymentTermState _updatePaymentTerm(
PaymentTermState paymentTermState, SavePaymentTermSuccess action) {
return paymentTermState
.rebuild((b) => b..map[action.paymentTerm.id] = action.paymentTerm);
}
PaymentTermState _setLoadedPaymentTerm(
PaymentTermState paymentTermState, LoadPaymentTermSuccess action) {
return paymentTermState
.rebuild((b) => b..map[action.paymentTerm.id] = action.paymentTerm);
}
PaymentTermState _setLoadedPaymentTerms(
PaymentTermState paymentTermState, LoadPaymentTermsSuccess action) =>
paymentTermState.loadPaymentTerms(action.paymentTerms);

View File

@ -0,0 +1,68 @@
import 'package:invoiceninja_flutter/data/models/payment_term_model.dart';
import 'package:memoize/memoize.dart';
import 'package:built_collection/built_collection.dart';
import 'package:invoiceninja_flutter/redux/ui/list_ui_state.dart';
var memoizedDropdownPaymentTermList = memo3((BuiltMap<String, PaymentTermEntity>
paymentTermMap,
BuiltList<String> paymentTermList,
String clientId) =>
dropdownPaymentTermsSelector(paymentTermMap, paymentTermList, clientId));
List<String> dropdownPaymentTermsSelector(
BuiltMap<String, PaymentTermEntity> paymentTermMap,
BuiltList<String> paymentTermList,
String clientId) {
final list = paymentTermList.where((paymentTermId) {
final paymentTerm = paymentTermMap[paymentTermId];
/*
if (clientId != null && clientId > 0 && paymentTerm.clientId != clientId) {
return false;
}
*/
return paymentTerm.isActive;
}).toList();
list.sort((paymentTermAId, paymentTermBId) {
final paymentTermA = paymentTermMap[paymentTermAId];
final paymentTermB = paymentTermMap[paymentTermBId];
return paymentTermA.compareTo(paymentTermB, PaymentTermFields.name, true);
});
return list;
}
var memoizedFilteredPaymentTermList = memo3(
(BuiltMap<String, PaymentTermEntity> paymentTermMap,
BuiltList<String> paymentTermList,
ListUIState paymentTermListState) =>
filteredPaymentTermsSelector(
paymentTermMap, paymentTermList, paymentTermListState));
List<String> filteredPaymentTermsSelector(
BuiltMap<String, PaymentTermEntity> paymentTermMap,
BuiltList<String> paymentTermList,
ListUIState paymentTermListState) {
final list = paymentTermList.where((paymentTermId) {
final paymentTerm = paymentTermMap[paymentTermId];
if (!paymentTerm.matchesStates(paymentTermListState.stateFilters)) {
return false;
}
return paymentTerm.matchesFilter(paymentTermListState.filter);
}).toList();
list.sort((paymentTermAId, paymentTermBId) {
final paymentTermA = paymentTermMap[paymentTermAId];
final paymentTermB = paymentTermMap[paymentTermBId];
return paymentTermA.compareTo(paymentTermB, paymentTermListState.sortField,
paymentTermListState.sortAscending);
});
return list;
}
bool hasPaymentTermChanges(PaymentTermEntity paymentTerm,
BuiltMap<String, PaymentTermEntity> paymentTermMap) =>
paymentTerm.isNew
? paymentTerm.isChanged
: paymentTerm != paymentTermMap[paymentTerm.id];

View File

@ -0,0 +1,89 @@
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/constants.dart';
import 'package:invoiceninja_flutter/data/models/payment_term_model.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';
part 'payment_term_state.g.dart';
abstract class PaymentTermState
implements Built<PaymentTermState, PaymentTermStateBuilder> {
factory PaymentTermState() {
return _$PaymentTermState._(
lastUpdated: 0,
map: BuiltMap<String, PaymentTermEntity>(),
list: BuiltList<String>(),
);
}
PaymentTermState._();
@override
@memoized
int get hashCode;
@nullable
int get lastUpdated;
BuiltMap<String, PaymentTermEntity> get map;
BuiltList<String> get list;
bool get isStale {
if (!isLoaded) {
return true;
}
return DateTime.now().millisecondsSinceEpoch - lastUpdated >
kMillisecondsToRefreshData;
}
bool get isLoaded => lastUpdated != null && lastUpdated > 0;
PaymentTermState loadPaymentTerms(BuiltList<PaymentTermEntity> clients) {
final map = Map<String, PaymentTermEntity>.fromIterable(
clients,
key: (dynamic item) => item.id,
value: (dynamic item) => item,
);
return rebuild((b) => b
..lastUpdated = DateTime.now().millisecondsSinceEpoch
..map.addAll(map)
..list.replace((map.keys.toList() + list.toList()).toSet().toList()));
}
static Serializer<PaymentTermState> get serializer =>
_$paymentTermStateSerializer;
}
abstract class PaymentTermUIState extends Object
with EntityUIState
implements Built<PaymentTermUIState, PaymentTermUIStateBuilder> {
factory PaymentTermUIState() {
return _$PaymentTermUIState._(
listUIState: ListUIState(PaymentTermFields.name),
editing: PaymentTermEntity(),
selectedId: '',
);
}
PaymentTermUIState._();
@override
@memoized
int get hashCode;
@nullable
PaymentTermEntity get editing;
@override
bool get isCreatingNew => editing.isNew;
@override
String get editingId => editing.id;
static Serializer<PaymentTermUIState> get serializer =>
_$paymentTermUIStateSerializer;
}

View File

@ -0,0 +1,421 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'payment_term_state.dart';
// **************************************************************************
// BuiltValueGenerator
// **************************************************************************
Serializer<PaymentTermState> _$paymentTermStateSerializer =
new _$PaymentTermStateSerializer();
Serializer<PaymentTermUIState> _$paymentTermUIStateSerializer =
new _$PaymentTermUIStateSerializer();
class _$PaymentTermStateSerializer
implements StructuredSerializer<PaymentTermState> {
@override
final Iterable<Type> types = const [PaymentTermState, _$PaymentTermState];
@override
final String wireName = 'PaymentTermState';
@override
Iterable<Object> serialize(Serializers serializers, PaymentTermState object,
{FullType specifiedType = FullType.unspecified}) {
final result = <Object>[
'map',
serializers.serialize(object.map,
specifiedType: const FullType(BuiltMap, const [
const FullType(String),
const FullType(PaymentTermEntity)
])),
'list',
serializers.serialize(object.list,
specifiedType:
const FullType(BuiltList, const [const FullType(String)])),
];
if (object.lastUpdated != null) {
result
..add('lastUpdated')
..add(serializers.serialize(object.lastUpdated,
specifiedType: const FullType(int)));
}
return result;
}
@override
PaymentTermState deserialize(
Serializers serializers, Iterable<Object> serialized,
{FullType specifiedType = FullType.unspecified}) {
final result = new PaymentTermStateBuilder();
final iterator = serialized.iterator;
while (iterator.moveNext()) {
final key = iterator.current as String;
iterator.moveNext();
final dynamic value = iterator.current;
switch (key) {
case 'lastUpdated':
result.lastUpdated = serializers.deserialize(value,
specifiedType: const FullType(int)) as int;
break;
case 'map':
result.map.replace(serializers.deserialize(value,
specifiedType: const FullType(BuiltMap, const [
const FullType(String),
const FullType(PaymentTermEntity)
])));
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 _$PaymentTermUIStateSerializer
implements StructuredSerializer<PaymentTermUIState> {
@override
final Iterable<Type> types = const [PaymentTermUIState, _$PaymentTermUIState];
@override
final String wireName = 'PaymentTermUIState';
@override
Iterable<Object> serialize(Serializers serializers, PaymentTermUIState object,
{FullType specifiedType = FullType.unspecified}) {
final result = <Object>[
'listUIState',
serializers.serialize(object.listUIState,
specifiedType: const FullType(ListUIState)),
];
if (object.editing != null) {
result
..add('editing')
..add(serializers.serialize(object.editing,
specifiedType: const FullType(PaymentTermEntity)));
}
if (object.selectedId != null) {
result
..add('selectedId')
..add(serializers.serialize(object.selectedId,
specifiedType: const FullType(String)));
}
return result;
}
@override
PaymentTermUIState deserialize(
Serializers serializers, Iterable<Object> serialized,
{FullType specifiedType = FullType.unspecified}) {
final result = new PaymentTermUIStateBuilder();
final iterator = serialized.iterator;
while (iterator.moveNext()) {
final key = iterator.current as String;
iterator.moveNext();
final dynamic value = iterator.current;
switch (key) {
case 'editing':
result.editing.replace(serializers.deserialize(value,
specifiedType: const FullType(PaymentTermEntity))
as PaymentTermEntity);
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;
}
}
return result.build();
}
}
class _$PaymentTermState extends PaymentTermState {
@override
final int lastUpdated;
@override
final BuiltMap<String, PaymentTermEntity> map;
@override
final BuiltList<String> list;
factory _$PaymentTermState(
[void Function(PaymentTermStateBuilder) updates]) =>
(new PaymentTermStateBuilder()..update(updates)).build();
_$PaymentTermState._({this.lastUpdated, this.map, this.list}) : super._() {
if (map == null) {
throw new BuiltValueNullFieldError('PaymentTermState', 'map');
}
if (list == null) {
throw new BuiltValueNullFieldError('PaymentTermState', 'list');
}
}
@override
PaymentTermState rebuild(void Function(PaymentTermStateBuilder) updates) =>
(toBuilder()..update(updates)).build();
@override
PaymentTermStateBuilder toBuilder() =>
new PaymentTermStateBuilder()..replace(this);
@override
bool operator ==(Object other) {
if (identical(other, this)) return true;
return other is PaymentTermState &&
lastUpdated == other.lastUpdated &&
map == other.map &&
list == other.list;
}
int __hashCode;
@override
int get hashCode {
return __hashCode ??= $jf(
$jc($jc($jc(0, lastUpdated.hashCode), map.hashCode), list.hashCode));
}
@override
String toString() {
return (newBuiltValueToStringHelper('PaymentTermState')
..add('lastUpdated', lastUpdated)
..add('map', map)
..add('list', list))
.toString();
}
}
class PaymentTermStateBuilder
implements Builder<PaymentTermState, PaymentTermStateBuilder> {
_$PaymentTermState _$v;
int _lastUpdated;
int get lastUpdated => _$this._lastUpdated;
set lastUpdated(int lastUpdated) => _$this._lastUpdated = lastUpdated;
MapBuilder<String, PaymentTermEntity> _map;
MapBuilder<String, PaymentTermEntity> get map =>
_$this._map ??= new MapBuilder<String, PaymentTermEntity>();
set map(MapBuilder<String, PaymentTermEntity> map) => _$this._map = map;
ListBuilder<String> _list;
ListBuilder<String> get list => _$this._list ??= new ListBuilder<String>();
set list(ListBuilder<String> list) => _$this._list = list;
PaymentTermStateBuilder();
PaymentTermStateBuilder get _$this {
if (_$v != null) {
_lastUpdated = _$v.lastUpdated;
_map = _$v.map?.toBuilder();
_list = _$v.list?.toBuilder();
_$v = null;
}
return this;
}
@override
void replace(PaymentTermState other) {
if (other == null) {
throw new ArgumentError.notNull('other');
}
_$v = other as _$PaymentTermState;
}
@override
void update(void Function(PaymentTermStateBuilder) updates) {
if (updates != null) updates(this);
}
@override
_$PaymentTermState build() {
_$PaymentTermState _$result;
try {
_$result = _$v ??
new _$PaymentTermState._(
lastUpdated: lastUpdated, map: map.build(), list: list.build());
} catch (_) {
String _$failedField;
try {
_$failedField = 'map';
map.build();
_$failedField = 'list';
list.build();
} catch (e) {
throw new BuiltValueNestedFieldError(
'PaymentTermState', _$failedField, e.toString());
}
rethrow;
}
replace(_$result);
return _$result;
}
}
class _$PaymentTermUIState extends PaymentTermUIState {
@override
final PaymentTermEntity editing;
@override
final ListUIState listUIState;
@override
final String selectedId;
@override
final Completer<SelectableEntity> saveCompleter;
@override
final Completer<Null> cancelCompleter;
factory _$PaymentTermUIState(
[void Function(PaymentTermUIStateBuilder) updates]) =>
(new PaymentTermUIStateBuilder()..update(updates)).build();
_$PaymentTermUIState._(
{this.editing,
this.listUIState,
this.selectedId,
this.saveCompleter,
this.cancelCompleter})
: super._() {
if (listUIState == null) {
throw new BuiltValueNullFieldError('PaymentTermUIState', 'listUIState');
}
}
@override
PaymentTermUIState rebuild(
void Function(PaymentTermUIStateBuilder) updates) =>
(toBuilder()..update(updates)).build();
@override
PaymentTermUIStateBuilder toBuilder() =>
new PaymentTermUIStateBuilder()..replace(this);
@override
bool operator ==(Object other) {
if (identical(other, this)) return true;
return other is PaymentTermUIState &&
editing == other.editing &&
listUIState == other.listUIState &&
selectedId == other.selectedId &&
saveCompleter == other.saveCompleter &&
cancelCompleter == other.cancelCompleter;
}
int __hashCode;
@override
int get hashCode {
return __hashCode ??= $jf($jc(
$jc(
$jc($jc($jc(0, editing.hashCode), listUIState.hashCode),
selectedId.hashCode),
saveCompleter.hashCode),
cancelCompleter.hashCode));
}
@override
String toString() {
return (newBuiltValueToStringHelper('PaymentTermUIState')
..add('editing', editing)
..add('listUIState', listUIState)
..add('selectedId', selectedId)
..add('saveCompleter', saveCompleter)
..add('cancelCompleter', cancelCompleter))
.toString();
}
}
class PaymentTermUIStateBuilder
implements Builder<PaymentTermUIState, PaymentTermUIStateBuilder> {
_$PaymentTermUIState _$v;
PaymentTermEntityBuilder _editing;
PaymentTermEntityBuilder get editing =>
_$this._editing ??= new PaymentTermEntityBuilder();
set editing(PaymentTermEntityBuilder 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;
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;
PaymentTermUIStateBuilder();
PaymentTermUIStateBuilder get _$this {
if (_$v != null) {
_editing = _$v.editing?.toBuilder();
_listUIState = _$v.listUIState?.toBuilder();
_selectedId = _$v.selectedId;
_saveCompleter = _$v.saveCompleter;
_cancelCompleter = _$v.cancelCompleter;
_$v = null;
}
return this;
}
@override
void replace(PaymentTermUIState other) {
if (other == null) {
throw new ArgumentError.notNull('other');
}
_$v = other as _$PaymentTermUIState;
}
@override
void update(void Function(PaymentTermUIStateBuilder) updates) {
if (updates != null) updates(this);
}
@override
_$PaymentTermUIState build() {
_$PaymentTermUIState _$result;
try {
_$result = _$v ??
new _$PaymentTermUIState._(
editing: _editing?.build(),
listUIState: listUIState.build(),
selectedId: selectedId,
saveCompleter: saveCompleter,
cancelCompleter: cancelCompleter);
} catch (_) {
String _$failedField;
try {
_$failedField = 'editing';
_editing?.build();
_$failedField = 'listUIState';
listUIState.build();
} catch (e) {
throw new BuiltValueNestedFieldError(
'PaymentTermUIState', _$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,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

@ -24,6 +24,8 @@ import 'package:invoiceninja_flutter/redux/user/user_actions.dart';
import 'package:invoiceninja_flutter/redux/vendor/vendor_actions.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/redux/payment_term/payment_term_actions.dart';
import 'package:invoiceninja_flutter/redux/design/design_actions.dart';
import 'package:invoiceninja_flutter/redux/credit/credit_actions.dart';
@ -405,6 +407,17 @@ Reducer<BuiltList<HistoryRecord>> historyReducer = combineReducers([
_addToHistory(historyList,
HistoryRecord(id: action.group.id, entityType: EntityType.group))),
// STARTER: history - do not remove comment
TypedReducer<BuiltList<HistoryRecord>, ViewPaymentTerm>(
(historyList, action) => _addToHistory(
historyList,
HistoryRecord(
id: action.paymentTermId, entityType: EntityType.paymentTerm))),
TypedReducer<BuiltList<HistoryRecord>, EditPaymentTerm>(
(historyList, action) => _addToHistory(
historyList,
HistoryRecord(
id: action.paymentTerm.id, entityType: EntityType.paymentTerm))),
TypedReducer<BuiltList<HistoryRecord>, EditDesign>((historyList, action) =>
_addToHistory(historyList,
HistoryRecord(id: action.design.id, entityType: EntityType.design))),

View File

@ -27,6 +27,8 @@ import 'package:invoiceninja_flutter/redux/task/task_reducer.dart';
import 'package:invoiceninja_flutter/redux/vendor/vendor_reducer.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/redux/payment_term/payment_term_reducer.dart';
import 'package:invoiceninja_flutter/redux/design/design_reducer.dart';
import 'package:invoiceninja_flutter/redux/credit/credit_reducer.dart';
@ -70,6 +72,8 @@ UIState uiReducer(UIState state, dynamic action) {
.replace(dashboardUIReducer(state.dashboardUIState, action))
..reportsUIState.replace(reportsUIReducer(state.reportsUIState, action))
// STARTER: reducer - do not remove comment
..paymentTermUIState
.replace(paymentTermUIReducer(state.paymentTermUIState, action))
..designUIState.replace(designUIReducer(state.designUIState, action))
..creditUIState.replace(creditUIReducer(state.creditUIState, action))
..userUIState.replace(userUIReducer(state.userUIState, action))

View File

@ -17,6 +17,8 @@ import 'package:invoiceninja_flutter/redux/task/task_state.dart';
import 'package:invoiceninja_flutter/redux/vendor/vendor_state.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/redux/payment_term/payment_term_state.dart';
import 'package:invoiceninja_flutter/redux/design/design_state.dart';
import 'package:invoiceninja_flutter/redux/credit/credit_state.dart';
@ -40,6 +42,8 @@ abstract class UIState implements Built<UIState, UIStateBuilder> {
clientUIState: ClientUIState(),
invoiceUIState: InvoiceUIState(),
// STARTER: constructor - do not remove comment
paymentTermUIState: PaymentTermUIState(),
designUIState: DesignUIState(),
creditUIState: CreditUIState(),
userUIState: UserUIState(),
@ -90,6 +94,8 @@ abstract class UIState implements Built<UIState, UIStateBuilder> {
InvoiceUIState get invoiceUIState;
// STARTER: properties - do not remove comment
PaymentTermUIState get paymentTermUIState;
DesignUIState get designUIState;
CreditUIState get creditUIState;

View File

@ -42,6 +42,9 @@ class _$UIStateSerializer implements StructuredSerializer<UIState> {
'invoiceUIState',
serializers.serialize(object.invoiceUIState,
specifiedType: const FullType(InvoiceUIState)),
'paymentTermUIState',
serializers.serialize(object.paymentTermUIState,
specifiedType: const FullType(PaymentTermUIState)),
'designUIState',
serializers.serialize(object.designUIState,
specifiedType: const FullType(DesignUIState)),
@ -165,6 +168,11 @@ class _$UIStateSerializer implements StructuredSerializer<UIState> {
result.invoiceUIState.replace(serializers.deserialize(value,
specifiedType: const FullType(InvoiceUIState)) as InvoiceUIState);
break;
case 'paymentTermUIState':
result.paymentTermUIState.replace(serializers.deserialize(value,
specifiedType: const FullType(PaymentTermUIState))
as PaymentTermUIState);
break;
case 'designUIState':
result.designUIState.replace(serializers.deserialize(value,
specifiedType: const FullType(DesignUIState)) as DesignUIState);
@ -259,6 +267,8 @@ class _$UIState extends UIState {
@override
final InvoiceUIState invoiceUIState;
@override
final PaymentTermUIState paymentTermUIState;
@override
final DesignUIState designUIState;
@override
final CreditUIState creditUIState;
@ -304,6 +314,7 @@ class _$UIState extends UIState {
this.productUIState,
this.clientUIState,
this.invoiceUIState,
this.paymentTermUIState,
this.designUIState,
this.creditUIState,
this.userUIState,
@ -344,6 +355,9 @@ class _$UIState extends UIState {
if (invoiceUIState == null) {
throw new BuiltValueNullFieldError('UIState', 'invoiceUIState');
}
if (paymentTermUIState == null) {
throw new BuiltValueNullFieldError('UIState', 'paymentTermUIState');
}
if (designUIState == null) {
throw new BuiltValueNullFieldError('UIState', 'designUIState');
}
@ -413,6 +427,7 @@ class _$UIState extends UIState {
productUIState == other.productUIState &&
clientUIState == other.clientUIState &&
invoiceUIState == other.invoiceUIState &&
paymentTermUIState == other.paymentTermUIState &&
designUIState == other.designUIState &&
creditUIState == other.creditUIState &&
userUIState == other.userUIState &&
@ -451,11 +466,11 @@ class _$UIState extends UIState {
$jc(
$jc(
$jc(
$jc($jc($jc($jc($jc($jc($jc($jc(0, selectedCompanyIndex.hashCode), currentRoute.hashCode), previousRoute.hashCode), filterEntityId.hashCode), filterEntityType.hashCode), filter.hashCode), filterClearedAt.hashCode),
dashboardUIState.hashCode),
productUIState.hashCode),
clientUIState.hashCode),
invoiceUIState.hashCode),
$jc($jc($jc($jc($jc($jc($jc($jc($jc(0, selectedCompanyIndex.hashCode), currentRoute.hashCode), previousRoute.hashCode), filterEntityId.hashCode), filterEntityType.hashCode), filter.hashCode), filterClearedAt.hashCode), dashboardUIState.hashCode),
productUIState.hashCode),
clientUIState.hashCode),
invoiceUIState.hashCode),
paymentTermUIState.hashCode),
designUIState.hashCode),
creditUIState.hashCode),
userUIState.hashCode),
@ -487,6 +502,7 @@ class _$UIState extends UIState {
..add('productUIState', productUIState)
..add('clientUIState', clientUIState)
..add('invoiceUIState', invoiceUIState)
..add('paymentTermUIState', paymentTermUIState)
..add('designUIState', designUIState)
..add('creditUIState', creditUIState)
..add('userUIState', userUIState)
@ -566,6 +582,12 @@ class UIStateBuilder implements Builder<UIState, UIStateBuilder> {
set invoiceUIState(InvoiceUIStateBuilder invoiceUIState) =>
_$this._invoiceUIState = invoiceUIState;
PaymentTermUIStateBuilder _paymentTermUIState;
PaymentTermUIStateBuilder get paymentTermUIState =>
_$this._paymentTermUIState ??= new PaymentTermUIStateBuilder();
set paymentTermUIState(PaymentTermUIStateBuilder paymentTermUIState) =>
_$this._paymentTermUIState = paymentTermUIState;
DesignUIStateBuilder _designUIState;
DesignUIStateBuilder get designUIState =>
_$this._designUIState ??= new DesignUIStateBuilder();
@ -672,6 +694,7 @@ class UIStateBuilder implements Builder<UIState, UIStateBuilder> {
_productUIState = _$v.productUIState?.toBuilder();
_clientUIState = _$v.clientUIState?.toBuilder();
_invoiceUIState = _$v.invoiceUIState?.toBuilder();
_paymentTermUIState = _$v.paymentTermUIState?.toBuilder();
_designUIState = _$v.designUIState?.toBuilder();
_creditUIState = _$v.creditUIState?.toBuilder();
_userUIState = _$v.userUIState?.toBuilder();
@ -722,6 +745,7 @@ class UIStateBuilder implements Builder<UIState, UIStateBuilder> {
productUIState: productUIState.build(),
clientUIState: clientUIState.build(),
invoiceUIState: invoiceUIState.build(),
paymentTermUIState: paymentTermUIState.build(),
designUIState: designUIState.build(),
creditUIState: creditUIState.build(),
userUIState: userUIState.build(),
@ -748,6 +772,8 @@ class UIStateBuilder implements Builder<UIState, UIStateBuilder> {
clientUIState.build();
_$failedField = 'invoiceUIState';
invoiceUIState.build();
_$failedField = 'paymentTermUIState';
paymentTermUIState.build();
_$failedField = 'designUIState';
designUIState.build();
_$failedField = 'creditUIState';

View File

@ -77,7 +77,8 @@ List<String> gmailUserList(BuiltMap<String, UserEntity> userMap) {
return userList(userMap).where((userId) {
final user = (userMap[userId] ?? UserEntity) as UserEntity;
return user.isActive && user.oauthProvider == UserEntity.OAUTH_PROVIDER_GOOGLE;
return user.isActive &&
user.oauthProvider == UserEntity.OAUTH_PROVIDER_GOOGLE;
}).toList();
}

View File

@ -371,7 +371,9 @@ class _AppBottomBarState extends State<AppBottomBar> {
tooltip: localization.filter,
icon: Icon(Icons.filter_list),
onPressed: _showFilterStateSheet,
color: store.state.getListState(widget.entityType).hasStateFilters
color: store.state
.getListState(widget.entityType)
.hasStateFilters
? Theme.of(context).accentColor
: null,
),
@ -380,10 +382,11 @@ class _AppBottomBarState extends State<AppBottomBar> {
tooltip: localization.filter,
icon: Icon(Icons.filter),
onPressed: _showFilterStatusSheet,
color:
store.state.getListState(widget.entityType).hasStatusFilters
? Theme.of(context).accentColor
: null,
color: store.state
.getListState(widget.entityType)
.hasStatusFilters
? Theme.of(context).accentColor
: null,
),
if (widget.customValues1.isNotEmpty)
IconButton(

View File

@ -125,8 +125,8 @@ class ListScaffold extends StatelessWidget {
state.prefState.isHistoryFloated) {
Scaffold.of(context).openEndDrawer();
} else {
store.dispatch(
UserPreferencesChanged(sidebar: AppSidebar.history));
store.dispatch(UserPreferencesChanged(
sidebar: AppSidebar.history));
}
},
),

View File

@ -10,7 +10,6 @@ import 'package:invoiceninja_flutter/redux/reports/reports_actions.dart';
import 'package:invoiceninja_flutter/redux/settings/settings_actions.dart';
import 'package:invoiceninja_flutter/redux/ui/pref_state.dart';
import 'package:invoiceninja_flutter/ui/app/app_builder.dart';
import 'package:invoiceninja_flutter/ui/app/forms/app_dropdown_button.dart';
import 'package:invoiceninja_flutter/ui/app/history_drawer_vm.dart';
import 'package:invoiceninja_flutter/ui/app/icon_text.dart';
import 'package:invoiceninja_flutter/ui/app/menu_drawer_vm.dart';

View File

@ -18,7 +18,7 @@ class ViewScaffold extends StatelessWidget {
this.floatingActionButton,
this.appBarBottom,
this.isSettings = false,
@required this.isFilter,
this.isFilter = false,
this.onBackPressed,
});

View File

@ -1,8 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:invoiceninja_flutter/constants.dart';
import 'package:invoiceninja_flutter/data/models/company_model.dart';
import 'package:invoiceninja_flutter/data/models/entities.dart';
import 'package:invoiceninja_flutter/data/models/payment_term_model.dart';
import 'package:invoiceninja_flutter/ui/app/entity_dropdown.dart';
import 'package:invoiceninja_flutter/ui/app/forms/decorated_form_field.dart';
import 'package:invoiceninja_flutter/ui/client/edit/client_edit_vm.dart';

View File

@ -0,0 +1,106 @@
import 'package:flutter/foundation.dart';
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/payment_term/edit/payment_term_edit_vm.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
class PaymentTermEdit extends StatefulWidget {
const PaymentTermEdit({
Key key,
@required this.viewModel,
}) : super(key: key);
final PaymentTermEditVM viewModel;
@override
_PaymentTermEditState createState() => _PaymentTermEditState();
}
class _PaymentTermEditState extends State<PaymentTermEdit> {
static final GlobalKey<FormState> _formKey =
GlobalKey<FormState>(debugLabel: '_paymentTermEdit');
final _debouncer = Debouncer();
// STARTER: controllers - do not remove comment
List<TextEditingController> _controllers = [];
@override
void didChangeDependencies() {
_controllers = [
// STARTER: array - do not remove comment
];
_controllers.forEach((controller) => controller.removeListener(_onChanged));
final paymentTerm = widget.viewModel.paymentTerm;
// STARTER: read value - do not remove comment
_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 paymentTerm = widget.viewModel.paymentTerm.rebuild((b) => b
// STARTER: set value - do not remove comment
);
if (paymentTerm != widget.viewModel.paymentTerm) {
widget.viewModel.onChanged(paymentTerm);
}
});
}
@override
Widget build(BuildContext context) {
final viewModel = widget.viewModel;
final localization = AppLocalization.of(context);
final paymentTerm = viewModel.paymentTerm;
return EditScaffold(
title: localization.editPaymentTerm,
onCancelPressed: (context) => viewModel.onCancelPressed(context),
onSavePressed: (context) {
final bool isValid = _formKey.currentState.validate();
/*
setState(() {
_autoValidate = !isValid;
});
*/
if (!isValid) {
return;
}
viewModel.onSavePressed(context);
},
body: Form(
key: _formKey,
child: Builder(builder: (BuildContext context) {
return ListView(
children: <Widget>[
FormCard(
children: <Widget>[
// STARTER: widgets - do not remove comment
],
),
],
);
})),
);
}
}

View File

@ -0,0 +1,106 @@
import 'dart:async';
import 'package:flutter/foundation.dart';
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:invoiceninja_flutter/ui/payment_term/payment_term_screen.dart';
import 'package:invoiceninja_flutter/utils/platforms.dart';
import 'package:redux/redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/ui/app/dialogs/error_dialog.dart';
import 'package:invoiceninja_flutter/ui/payment_term/view/payment_term_view_vm.dart';
import 'package:invoiceninja_flutter/redux/payment_term/payment_term_actions.dart';
import 'package:invoiceninja_flutter/data/models/payment_term_model.dart';
import 'package:invoiceninja_flutter/ui/payment_term/edit/payment_term_edit.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
class PaymentTermEditScreen extends StatelessWidget {
const PaymentTermEditScreen({Key key}) : super(key: key);
static const String route = '/payment_term/edit';
@override
Widget build(BuildContext context) {
return StoreConnector<AppState, PaymentTermEditVM>(
converter: (Store<AppState> store) {
return PaymentTermEditVM.fromStore(store);
},
builder: (context, viewModel) {
return PaymentTermEdit(
viewModel: viewModel,
key: ValueKey(viewModel.paymentTerm.id),
);
},
);
}
}
class PaymentTermEditVM {
PaymentTermEditVM({
@required this.state,
@required this.paymentTerm,
@required this.company,
@required this.onChanged,
@required this.isSaving,
@required this.origPaymentTerm,
@required this.onSavePressed,
@required this.onCancelPressed,
@required this.isLoading,
});
factory PaymentTermEditVM.fromStore(Store<AppState> store) {
final state = store.state;
final paymentTerm = state.paymentTermUIState.editing;
return PaymentTermEditVM(
state: state,
isLoading: state.isLoading,
isSaving: state.isSaving,
origPaymentTerm: state.paymentTermState.map[paymentTerm.id],
paymentTerm: paymentTerm,
company: state.company,
onChanged: (PaymentTermEntity paymentTerm) {
store.dispatch(UpdatePaymentTerm(paymentTerm));
},
onCancelPressed: (BuildContext context) {
createEntity(
context: context, entity: PaymentTermEntity(), force: true);
},
onSavePressed: (BuildContext context) {
final Completer<PaymentTermEntity> completer =
new Completer<PaymentTermEntity>();
store.dispatch(SavePaymentTermRequest(
completer: completer, paymentTerm: paymentTerm));
return completer.future.then((savedPaymentTerm) {
if (isMobile(context)) {
store.dispatch(UpdateCurrentRoute(PaymentTermViewScreen.route));
if (paymentTerm.isNew) {
Navigator.of(context)
.pushReplacementNamed(PaymentTermViewScreen.route);
} else {
Navigator.of(context).pop(savedPaymentTerm);
}
} else {
viewEntity(context: context, entity: savedPaymentTerm, force: true);
}
}).catchError((Object error) {
showDialog<ErrorDialog>(
context: context,
builder: (BuildContext context) {
return ErrorDialog(error);
});
});
},
);
}
final PaymentTermEntity paymentTerm;
final CompanyEntity company;
final Function(PaymentTermEntity) onChanged;
final Function(BuildContext) onSavePressed;
final Function(BuildContext) onCancelPressed;
final bool isLoading;
final bool isSaving;
final PaymentTermEntity origPaymentTerm;
final AppState state;
}

View File

@ -0,0 +1,92 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/data/models/payment_term_model.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/payment_term/payment_term_actions.dart';
import 'package:invoiceninja_flutter/redux/ui/pref_state.dart';
import 'package:invoiceninja_flutter/ui/app/entities/entity_actions_dialog.dart';
import 'package:invoiceninja_flutter/ui/app/help_text.dart';
import 'package:invoiceninja_flutter/ui/app/lists/list_divider.dart';
import 'package:invoiceninja_flutter/ui/app/loading_indicator.dart';
import 'package:invoiceninja_flutter/ui/app/presenters/entity_presenter.dart';
import 'package:invoiceninja_flutter/ui/payment_term/payment_term_presenter.dart';
import 'package:invoiceninja_flutter/ui/app/tables/entity_datatable.dart';
import 'package:invoiceninja_flutter/ui/payment_term/payment_term_list_item.dart';
import 'package:invoiceninja_flutter/ui/payment_term/payment_term_list_vm.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
class PaymentTermList extends StatefulWidget {
const PaymentTermList({
Key key,
@required this.viewModel,
}) : super(key: key);
final PaymentTermListVM viewModel;
@override
_PaymentTermListState createState() => _PaymentTermListState();
}
class _PaymentTermListState extends State<PaymentTermList> {
EntityDataTableSource dataTableSource;
@override
Widget build(BuildContext context) {
final viewModel = widget.viewModel;
final state = viewModel.state;
final listUIState = state.uiState.paymentTermUIState.listUIState;
final isInMultiselect = listUIState.isInMultiselect();
if (!viewModel.isLoaded) {
return viewModel.isLoading ? LoadingIndicator() : SizedBox();
} else if (viewModel.paymentTermMap.isEmpty) {
return HelpText(AppLocalization.of(context).noRecordsFound);
}
return RefreshIndicator(
onRefresh: () => viewModel.onRefreshed(context),
child: ListView.separated(
separatorBuilder: (context, index) => ListDivider(),
itemCount: viewModel.paymentTermList.length,
itemBuilder: (BuildContext context, index) {
final paymentTermId = viewModel.paymentTermList[index];
final paymentTerm = viewModel.paymentTermMap[paymentTermId];
return PaymentTermListItem(
user: viewModel.state.user,
filter: viewModel.filter,
paymentTerm: paymentTerm,
onEntityAction: (EntityAction action) {
if (action == EntityAction.more) {
showEntityActionsDialog(
entities: [paymentTerm],
context: context,
);
} else {
handlePaymentTermAction(context, [paymentTerm], action);
}
},
onTap: () => viewModel.onPaymentTermTap(context, paymentTerm),
onLongPress: () async {
final longPressIsSelection =
state.prefState.longPressSelectionIsDefault ?? true;
if (longPressIsSelection && !isInMultiselect) {
handlePaymentTermAction(
context, [paymentTerm], EntityAction.toggleMultiselect);
} else {
showEntityActionsDialog(
entities: [paymentTerm],
context: context,
);
}
},
isChecked:
isInMultiselect && listUIState.isSelected(paymentTerm.id),
);
}),
);
}
}

View File

@ -0,0 +1,105 @@
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/payment_term_model.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/foundation.dart';
import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/ui/app/dismissible_entity.dart';
class PaymentTermListItem extends StatelessWidget {
const PaymentTermListItem({
@required this.user,
@required this.onEntityAction,
@required this.onTap,
@required this.onLongPress,
@required this.paymentTerm,
@required this.filter,
this.onCheckboxChanged,
this.isChecked = false,
});
final UserEntity user;
final Function(EntityAction) onEntityAction;
final GestureTapCallback onTap;
final GestureTapCallback onLongPress;
final PaymentTermEntity paymentTerm;
final String filter;
final Function(bool) onCheckboxChanged;
final bool isChecked;
static final paymentTermItemKey =
(int id) => Key('__payment_term_item_${id}__');
@override
Widget build(BuildContext context) {
final store = StoreProvider.of<AppState>(context);
final state = store.state;
final uiState = state.uiState;
final paymentTermUIState = uiState.paymentTermUIState;
final listUIState = paymentTermUIState.listUIState;
final isInMultiselect = listUIState.isInMultiselect();
final showCheckbox = onCheckboxChanged != null || isInMultiselect;
final filterMatch = filter != null && filter.isNotEmpty
? paymentTerm.matchesFilterValue(filter)
: null;
final subtitle = filterMatch;
return DismissibleEntity(
userCompany: state.userCompany,
entity: paymentTerm,
isSelected: paymentTerm.id ==
(uiState.isEditing
? paymentTermUIState.editing.id
: paymentTermUIState.selectedId),
onEntityAction: onEntityAction,
child: ListTile(
onTap: isInMultiselect
? () => onEntityAction(EntityAction.toggleMultiselect)
: onTap,
onLongPress: onLongPress,
leading: showCheckbox
? IgnorePointer(
ignoring: listUIState.isInMultiselect(),
child: Checkbox(
value: isChecked,
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
onChanged: (value) => onCheckboxChanged(value),
activeColor: Theme.of(context).accentColor,
),
)
: null,
title: Container(
width: MediaQuery.of(context).size.width,
child: Row(
children: <Widget>[
Expanded(
child: Text(
paymentTerm.name,
style: Theme.of(context).textTheme.title,
),
),
Text(formatNumber(paymentTerm.listDisplayAmount, context),
style: Theme.of(context).textTheme.title),
],
),
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
subtitle != null && subtitle.isNotEmpty
? Text(
subtitle,
maxLines: 3,
overflow: TextOverflow.ellipsis,
)
: Container(),
EntityStateLabel(paymentTerm),
],
),
),
);
}
}

View File

@ -0,0 +1,166 @@
import 'dart:async';
import 'package:invoiceninja_flutter/data/models/payment_term_model.dart';
import 'package:invoiceninja_flutter/ui/app/entities/entity_actions_dialog.dart';
import 'package:invoiceninja_flutter/ui/app/tables/entity_list.dart';
import 'package:invoiceninja_flutter/ui/payment_term/payment_term_list_item.dart';
import 'package:redux/redux.dart';
import 'package:invoiceninja_flutter/ui/design/design_presenter.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:flutter/material.dart';
import 'package:flutter/foundation.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/payment_term/payment_term_selectors.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/payment_term/payment_term_actions.dart';
class PaymentTermListBuilder extends StatelessWidget {
const PaymentTermListBuilder({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return StoreConnector<AppState, PaymentTermListVM>(
converter: PaymentTermListVM.fromStore,
builder: (context, viewModel) {
return EntityList(
isLoaded: viewModel.isLoaded,
entityType: EntityType.paymentTerm,
state: viewModel.state,
entityList: viewModel.paymentTermList,
onEntityTap: viewModel.onPaymentTermTap,
tableColumns: viewModel.tableColumns,
onRefreshed: viewModel.onRefreshed,
onClearEntityFilterPressed: viewModel.onClearEntityFilterPressed,
onViewEntityFilterPressed: viewModel.onViewEntityFilterPressed,
onSortColumn: viewModel.onSortColumn,
itemBuilder: (BuildContext context, index) {
final state = viewModel.state;
final paymentTermId = viewModel.paymentTermList[index];
final paymentTerm = viewModel.paymentTermMap[paymentTermId];
final listState = state.getListState(EntityType.paymentTerm);
final isInMultiselect = listState.isInMultiselect();
return PaymentTermListItem(
user: viewModel.state.user,
filter: viewModel.filter,
paymentTerm: paymentTerm,
onEntityAction: (EntityAction action) {
if (action == EntityAction.more) {
showEntityActionsDialog(
entities: [paymentTerm],
context: context,
);
} else {
handlePaymentTermAction(context, [paymentTerm], action);
}
},
onTap: () => viewModel.onPaymentTermTap(context, paymentTerm),
onLongPress: () async {
final longPressIsSelection =
state.prefState.longPressSelectionIsDefault ?? true;
if (longPressIsSelection && !isInMultiselect) {
handlePaymentTermAction(
context, [paymentTerm], EntityAction.toggleMultiselect);
} else {
showEntityActionsDialog(
entities: [paymentTerm],
context: context,
);
}
},
isChecked:
isInMultiselect && listState.isSelected(paymentTerm.id),
);
});
},
);
}
}
class PaymentTermListVM {
PaymentTermListVM({
@required this.state,
@required this.userCompany,
@required this.paymentTermList,
@required this.paymentTermMap,
@required this.filter,
@required this.isLoading,
@required this.isLoaded,
@required this.onPaymentTermTap,
@required this.listState,
@required this.onRefreshed,
@required this.onEntityAction,
@required this.onClearEntityFilterPressed,
@required this.onViewEntityFilterPressed,
@required this.onSortColumn,
this.tableColumns,
});
static PaymentTermListVM 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(LoadPaymentTerms(completer: completer, force: true));
return completer.future;
}
final state = store.state;
return PaymentTermListVM(
state: state,
userCompany: state.userCompany,
listState: state.paymentTermListState,
paymentTermList: memoizedFilteredPaymentTermList(
state.paymentTermState.map,
state.paymentTermState.list,
state.paymentTermListState),
paymentTermMap: state.paymentTermState.map,
isLoading: state.isLoading,
isLoaded: state.paymentTermState.isLoaded,
filter: state.paymentTermUIState.listUIState.filter,
onClearEntityFilterPressed: () =>
store.dispatch(FilterPaymentTermsByEntity()),
onViewEntityFilterPressed: (BuildContext context) => viewEntityById(
context: context,
entityId: state.paymentTermListState.filterEntityId,
entityType: state.paymentTermListState.filterEntityType),
onPaymentTermTap: (context, paymentTerm) {
if (store.state.paymentTermListState.isInMultiselect()) {
handlePaymentTermAction(
context, [paymentTerm], EntityAction.toggleMultiselect);
} else {
viewEntity(context: context, entity: paymentTerm);
}
},
onEntityAction: (BuildContext context, List<BaseEntity> paymentTerms,
EntityAction action) =>
handlePaymentTermAction(context, paymentTerms, action),
onRefreshed: (context) => _handleRefresh(context),
onSortColumn: (field) => store.dispatch(SortPaymentTerms(field)),
);
}
final AppState state;
final UserCompanyEntity userCompany;
final List<String> paymentTermList;
final BuiltMap<String, PaymentTermEntity> paymentTermMap;
final ListUIState listState;
final String filter;
final bool isLoading;
final bool isLoaded;
final Function(BuildContext, BaseEntity) onPaymentTermTap;
final Function(BuildContext) onRefreshed;
final Function(BuildContext, List<BaseEntity>, EntityAction) onEntityAction;
final Function onClearEntityFilterPressed;
final Function(BuildContext) onViewEntityFilterPressed;
final List<String> tableColumns;
final Function(String) onSortColumn;
}

View File

@ -0,0 +1,22 @@
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_state.dart';
import 'package:invoiceninja_flutter/ui/app/presenters/entity_presenter.dart';
class PaymentTermPresenter extends EntityPresenter {
static List<String> getTableFields(UserCompanyEntity userCompany) {
return [];
}
@override
Widget getField({String field, BuildContext context}) {
final state = StoreProvider.of<AppState>(context).state;
final paymentTerm = entity as InvoiceEntity;
switch (field) {
}
return super.getField(field: field, context: context);
}
}

View File

@ -0,0 +1,130 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/data/models/payment_term_model.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/payment_term/payment_term_actions.dart';
import 'package:invoiceninja_flutter/ui/app/app_bottom_bar.dart';
import 'package:invoiceninja_flutter/ui/app/forms/save_cancel_buttons.dart';
import 'package:invoiceninja_flutter/ui/app/list_scaffold.dart';
import 'package:invoiceninja_flutter/ui/app/entities/entity_actions_dialog.dart';
import 'package:invoiceninja_flutter/ui/app/list_filter.dart';
import 'package:invoiceninja_flutter/ui/payment_term/payment_term_list_vm.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/utils/platforms.dart';
import 'payment_term_screen_vm.dart';
class PaymentTermScreen extends StatelessWidget {
const PaymentTermScreen({
Key key,
@required this.viewModel,
}) : super(key: key);
static const String route = '/payment_term';
final PaymentTermScreenVM 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);
final listUIState = state.uiState.paymentTermUIState.listUIState;
final isInMultiselect = listUIState.isInMultiselect();
return ListScaffold(
isChecked: isInMultiselect &&
listUIState.selectedIds.length == viewModel.paymentTermList.length,
showCheckbox: isInMultiselect,
onHamburgerLongPress: () => store.dispatch(StartPaymentTermMultiselect()),
onCheckboxChanged: (value) {
final paymentTerms = viewModel.paymentTermList
.map<PaymentTermEntity>(
(paymentTermId) => viewModel.paymentTermMap[paymentTermId])
.where((paymentTerm) =>
value != listUIState.isSelected(paymentTerm.id))
.toList();
handlePaymentTermAction(
context, paymentTerms, EntityAction.toggleMultiselect);
},
appBarTitle: Text(localization.paymentTerms),
appBarActions: [
if (viewModel.isInMultiselect)
SaveCancelButtons(
saveLabel: localization.done,
onSavePressed: listUIState.selectedIds.isEmpty
? null
: (context) async {
final paymentTerms = listUIState.selectedIds
.map<PaymentTermEntity>((paymentTermId) =>
viewModel.paymentTermMap[paymentTermId])
.toList();
await showEntityActionsDialog(
entities: paymentTerms,
context: context,
multiselect: true,
completer: Completer<Null>()
..future.then<dynamic>((_) =>
store.dispatch(ClearPaymentTermMultiselect())),
);
},
onCancelPressed: (context) =>
store.dispatch(ClearPaymentTermMultiselect()),
),
],
body: PaymentTermListBuilder(),
bottomNavigationBar: AppBottomBar(
entityType: EntityType.paymentTerm,
onRefreshPressed: () => store.dispatch(LoadPaymentTerms(force: true)),
onSelectedSortField: (value) {
store.dispatch(SortPaymentTerms(value));
},
sortFields: [
PaymentTermFields.name,
PaymentTermFields.numDays,
],
onSelectedState: (EntityState state, value) {
store.dispatch(FilterPaymentTermsByState(state));
},
onCheckboxPressed: () {
if (store.state.paymentTermListState.isInMultiselect()) {
store.dispatch(ClearPaymentTermMultiselect());
} else {
store.dispatch(StartPaymentTermMultiselect());
}
},
onSelectedCustom1: (value) =>
store.dispatch(FilterPaymentTermsByCustom1(value)),
onSelectedCustom2: (value) =>
store.dispatch(FilterPaymentTermsByCustom2(value)),
onSelectedCustom3: (value) =>
store.dispatch(FilterPaymentTermsByCustom3(value)),
onSelectedCustom4: (value) =>
store.dispatch(FilterPaymentTermsByCustom4(value)),
),
floatingActionButton:
isMobile(context) && userCompany.canCreate(EntityType.paymentTerm)
? FloatingActionButton(
heroTag: 'payment_term_fab',
backgroundColor: Theme.of(context).primaryColorDark,
onPressed: () {
createEntityByType(
context: context, entityType: EntityType.paymentTerm);
},
child: Icon(
Icons.add,
color: Colors.white,
),
tooltip: localization.newPaymentTerm,
)
: null,
);
}
}

View File

@ -0,0 +1,62 @@
import 'package:built_collection/built_collection.dart';
import 'package:flutter/foundation.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/data/models/payment_term_model.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/payment_term/payment_term_actions.dart';
import 'package:invoiceninja_flutter/redux/payment_term/payment_term_selectors.dart';
import 'package:redux/redux.dart';
import 'payment_term_screen.dart';
class PaymentTermScreenBuilder extends StatelessWidget {
const PaymentTermScreenBuilder({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return StoreConnector<AppState, PaymentTermScreenVM>(
converter: PaymentTermScreenVM.fromStore,
builder: (context, vm) {
return PaymentTermScreen(
viewModel: vm,
);
},
);
}
}
class PaymentTermScreenVM {
PaymentTermScreenVM({
@required this.isInMultiselect,
@required this.paymentTermList,
@required this.userCompany,
@required this.onEntityAction,
@required this.paymentTermMap,
});
final bool isInMultiselect;
final UserCompanyEntity userCompany;
final List<String> paymentTermList;
final Function(BuildContext, List<BaseEntity>, EntityAction) onEntityAction;
final BuiltMap<String, PaymentTermEntity> paymentTermMap;
static PaymentTermScreenVM fromStore(Store<AppState> store) {
final state = store.state;
return PaymentTermScreenVM(
paymentTermMap: state.paymentTermState.map,
paymentTermList: memoizedFilteredPaymentTermList(
state.paymentTermState.map,
state.paymentTermState.list,
state.paymentTermListState),
userCompany: state.userCompany,
isInMultiselect: state.paymentTermListState.isInMultiselect(),
onEntityAction: (BuildContext context, List<BaseEntity> paymentTerms,
EntityAction action) =>
handlePaymentTermAction(context, paymentTerms, action),
);
}
}

View File

@ -0,0 +1,32 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/ui/app/view_scaffold.dart';
import 'package:invoiceninja_flutter/ui/payment_term/view/payment_term_view_vm.dart';
class PaymentTermView extends StatefulWidget {
const PaymentTermView({
Key key,
@required this.viewModel,
}) : super(key: key);
final PaymentTermViewVM viewModel;
@override
_PaymentTermViewState createState() => new _PaymentTermViewState();
}
class _PaymentTermViewState extends State<PaymentTermView> {
@override
Widget build(BuildContext context) {
final viewModel = widget.viewModel;
final userCompany = viewModel.state.userCompany;
final paymentTerm = viewModel.paymentTerm;
return ViewScaffold(
entity: paymentTerm,
body: ListView(
children: <Widget>[],
),
);
}
}

View File

@ -0,0 +1,80 @@
import 'dart:async';
import 'package:flutter/foundation.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/payment_term/payment_term_actions.dart';
import 'package:invoiceninja_flutter/data/models/payment_term_model.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/ui/payment_term/view/payment_term_view.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
class PaymentTermViewScreen extends StatelessWidget {
const PaymentTermViewScreen({Key key}) : super(key: key);
static const String route = '/payment_term/view';
@override
Widget build(BuildContext context) {
return StoreConnector<AppState, PaymentTermViewVM>(
converter: (Store<AppState> store) {
return PaymentTermViewVM.fromStore(store);
},
builder: (context, vm) {
return PaymentTermView(
viewModel: vm,
);
},
);
}
}
class PaymentTermViewVM {
PaymentTermViewVM({
@required this.state,
@required this.paymentTerm,
@required this.company,
@required this.onEntityAction,
@required this.onRefreshed,
@required this.isSaving,
@required this.isLoading,
@required this.isDirty,
});
factory PaymentTermViewVM.fromStore(Store<AppState> store) {
final state = store.state;
final paymentTerm =
state.paymentTermState.map[state.paymentTermUIState.selectedId] ??
PaymentTermEntity(id: state.paymentTermUIState.selectedId);
Future<Null> _handleRefresh(BuildContext context) {
final completer = snackBarCompleter<Null>(
context, AppLocalization.of(context).refreshComplete);
store.dispatch(
LoadPaymentTerm(completer: completer, paymentTermId: paymentTerm.id));
return completer.future;
}
return PaymentTermViewVM(
state: state,
company: state.company,
isSaving: state.isSaving,
isLoading: state.isLoading,
isDirty: paymentTerm.isNew,
paymentTerm: paymentTerm,
onRefreshed: (context) => _handleRefresh(context),
onEntityAction: (BuildContext context, EntityAction action) =>
handlePaymentTermAction(context, [paymentTerm], action),
);
}
final AppState state;
final PaymentTermEntity paymentTerm;
final CompanyEntity company;
final Function(BuildContext, EntityAction) onEntityAction;
final Function(BuildContext) onRefreshed;
final bool isSaving;
final bool isLoading;
final bool isDirty;
}

File diff suppressed because it is too large Load Diff

View File

@ -327,7 +327,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/$comment${lineBreak}$code/g" ./lib/main.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}"
@ -341,7 +341,7 @@ else
sed -i -e "s/$comment/$comment${lineBreak}$code/g" ./lib/data/models/serializers.dart
comment="STARTER: serializers - do not remove comment"
code="${Module}Entity,${Module}ListResponse,${Module}ItemResponse${lineBreak}"
code="${Module}Entity,${Module}ListResponse,${Module}ItemResponse,${lineBreak}"
sed -i -e "s/$comment/$comment${lineBreak}$code/g" ./lib/data/models/serializers.dart
comment="STARTER: import - do not remove comment"
@ -454,7 +454,7 @@ else
sed -i -e "s/$comment/$comment${lineBreak}$code/g" ./lib/utils/i18n.dart
comment="STARTER: entity type - do not remove comment"
code="static const EntityType ${module_camel} = _\$${module_camel}${lineBreak}"
code="static const EntityType ${module_camel} = _\$${module_camel};${lineBreak}"
sed -i -e "s/$comment/$comment${lineBreak}$code/g" ./lib/data/models/entities.dart
echo "Generating built files.."