Credits
This commit is contained in:
parent
8d42b7df68
commit
70f8ace04b
|
|
@ -14,7 +14,7 @@ abstract class CreditListResponse
|
|||
|
||||
CreditListResponse._();
|
||||
|
||||
BuiltList<CreditEntity> get data;
|
||||
BuiltList<InvoiceEntity> get data;
|
||||
|
||||
static Serializer<CreditListResponse> get serializer =>
|
||||
_$creditListResponseSerializer;
|
||||
|
|
@ -27,7 +27,7 @@ abstract class CreditItemResponse
|
|||
|
||||
CreditItemResponse._();
|
||||
|
||||
CreditEntity get data;
|
||||
InvoiceEntity get data;
|
||||
|
||||
static Serializer<CreditItemResponse> get serializer =>
|
||||
_$creditItemResponseSerializer;
|
||||
|
|
@ -46,110 +46,3 @@ class CreditFields {
|
|||
static const String archivedAt = 'archivedAt';
|
||||
static const String isDeleted = 'isDeleted';
|
||||
}
|
||||
|
||||
abstract class CreditEntity extends Object
|
||||
with BaseEntity, SelectableEntity
|
||||
implements Built<CreditEntity, CreditEntityBuilder> {
|
||||
factory CreditEntity() {
|
||||
return _$CreditEntity._(
|
||||
id: BaseEntity.nextId,
|
||||
isChanged: false,
|
||||
amount: 0.0,
|
||||
balance: 0.0,
|
||||
creditDate: '',
|
||||
creditNumber: '',
|
||||
privateNotes: '',
|
||||
publicNotes: '',
|
||||
clientId: 0,
|
||||
updatedAt: 0,
|
||||
archivedAt: 0,
|
||||
isDeleted: false,
|
||||
);
|
||||
}
|
||||
|
||||
CreditEntity._();
|
||||
|
||||
CreditEntity get clone => rebuild((b) => b
|
||||
..id = BaseEntity.nextId
|
||||
..isChanged = false
|
||||
..isDeleted = false);
|
||||
|
||||
@override
|
||||
EntityType get entityType {
|
||||
return EntityType.credit;
|
||||
}
|
||||
|
||||
double get amount;
|
||||
|
||||
double get balance;
|
||||
|
||||
@BuiltValueField(wireName: 'credit_date')
|
||||
String get creditDate;
|
||||
|
||||
@BuiltValueField(wireName: 'credit_number')
|
||||
String get creditNumber;
|
||||
|
||||
@BuiltValueField(wireName: 'private_notes')
|
||||
String get privateNotes;
|
||||
|
||||
@BuiltValueField(wireName: 'public_notes')
|
||||
String get publicNotes;
|
||||
|
||||
@BuiltValueField(wireName: 'client_id')
|
||||
int get clientId;
|
||||
|
||||
@override
|
||||
List<EntityAction> getActions(
|
||||
{UserCompanyEntity userCompany,
|
||||
ClientEntity client,
|
||||
bool includeEdit = false,
|
||||
bool multiselect = false}) {
|
||||
final actions = <EntityAction>[];
|
||||
|
||||
return actions..addAll(super.getActions(userCompany: userCompany));
|
||||
}
|
||||
|
||||
int compareTo(CreditEntity credit, String sortField, bool sortAscending) {
|
||||
int response = 0;
|
||||
final CreditEntity creditA = sortAscending ? this : credit;
|
||||
final CreditEntity creditB = sortAscending ? credit : this;
|
||||
|
||||
switch (sortField) {
|
||||
case CreditFields.amount:
|
||||
response = creditA.amount.compareTo(creditB.amount);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@override
|
||||
bool matchesFilter(String filter) {
|
||||
if (filter == null || filter.isEmpty) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return publicNotes.toLowerCase().contains(filter);
|
||||
}
|
||||
|
||||
@override
|
||||
String matchesFilterValue(String filter) {
|
||||
if (filter == null || filter.isEmpty) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
String get listDisplayName {
|
||||
return publicNotes;
|
||||
}
|
||||
|
||||
@override
|
||||
double get listDisplayAmount => null;
|
||||
|
||||
@override
|
||||
FormatNumberType get listDisplayAmountType => FormatNumberType.money;
|
||||
|
||||
static Serializer<CreditEntity> get serializer => _$creditEntitySerializer;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,6 @@ Serializer<CreditListResponse> _$creditListResponseSerializer =
|
|||
new _$CreditListResponseSerializer();
|
||||
Serializer<CreditItemResponse> _$creditItemResponseSerializer =
|
||||
new _$CreditItemResponseSerializer();
|
||||
Serializer<CreditEntity> _$creditEntitySerializer =
|
||||
new _$CreditEntitySerializer();
|
||||
|
||||
class _$CreditListResponseSerializer
|
||||
implements StructuredSerializer<CreditListResponse> {
|
||||
|
|
@ -27,7 +25,7 @@ class _$CreditListResponseSerializer
|
|||
'data',
|
||||
serializers.serialize(object.data,
|
||||
specifiedType:
|
||||
const FullType(BuiltList, const [const FullType(CreditEntity)])),
|
||||
const FullType(BuiltList, const [const FullType(InvoiceEntity)])),
|
||||
];
|
||||
|
||||
return result;
|
||||
|
|
@ -48,7 +46,7 @@ class _$CreditListResponseSerializer
|
|||
case 'data':
|
||||
result.data.replace(serializers.deserialize(value,
|
||||
specifiedType: const FullType(
|
||||
BuiltList, const [const FullType(CreditEntity)]))
|
||||
BuiltList, const [const FullType(InvoiceEntity)]))
|
||||
as BuiltList<Object>);
|
||||
break;
|
||||
}
|
||||
|
|
@ -71,7 +69,7 @@ class _$CreditItemResponseSerializer
|
|||
final result = <Object>[
|
||||
'data',
|
||||
serializers.serialize(object.data,
|
||||
specifiedType: const FullType(CreditEntity)),
|
||||
specifiedType: const FullType(InvoiceEntity)),
|
||||
];
|
||||
|
||||
return result;
|
||||
|
|
@ -91,178 +89,7 @@ class _$CreditItemResponseSerializer
|
|||
switch (key) {
|
||||
case 'data':
|
||||
result.data.replace(serializers.deserialize(value,
|
||||
specifiedType: const FullType(CreditEntity)) as CreditEntity);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result.build();
|
||||
}
|
||||
}
|
||||
|
||||
class _$CreditEntitySerializer implements StructuredSerializer<CreditEntity> {
|
||||
@override
|
||||
final Iterable<Type> types = const [CreditEntity, _$CreditEntity];
|
||||
@override
|
||||
final String wireName = 'CreditEntity';
|
||||
|
||||
@override
|
||||
Iterable<Object> serialize(Serializers serializers, CreditEntity object,
|
||||
{FullType specifiedType = FullType.unspecified}) {
|
||||
final result = <Object>[
|
||||
'amount',
|
||||
serializers.serialize(object.amount,
|
||||
specifiedType: const FullType(double)),
|
||||
'balance',
|
||||
serializers.serialize(object.balance,
|
||||
specifiedType: const FullType(double)),
|
||||
'credit_date',
|
||||
serializers.serialize(object.creditDate,
|
||||
specifiedType: const FullType(String)),
|
||||
'credit_number',
|
||||
serializers.serialize(object.creditNumber,
|
||||
specifiedType: const FullType(String)),
|
||||
'private_notes',
|
||||
serializers.serialize(object.privateNotes,
|
||||
specifiedType: const FullType(String)),
|
||||
'public_notes',
|
||||
serializers.serialize(object.publicNotes,
|
||||
specifiedType: const FullType(String)),
|
||||
'client_id',
|
||||
serializers.serialize(object.clientId,
|
||||
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(String)));
|
||||
}
|
||||
if (object.id != null) {
|
||||
result
|
||||
..add('id')
|
||||
..add(serializers.serialize(object.id,
|
||||
specifiedType: const FullType(String)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
CreditEntity deserialize(Serializers serializers, Iterable<Object> serialized,
|
||||
{FullType specifiedType = FullType.unspecified}) {
|
||||
final result = new CreditEntityBuilder();
|
||||
|
||||
final iterator = serialized.iterator;
|
||||
while (iterator.moveNext()) {
|
||||
final key = iterator.current as String;
|
||||
iterator.moveNext();
|
||||
final dynamic value = iterator.current;
|
||||
switch (key) {
|
||||
case 'amount':
|
||||
result.amount = serializers.deserialize(value,
|
||||
specifiedType: const FullType(double)) as double;
|
||||
break;
|
||||
case 'balance':
|
||||
result.balance = serializers.deserialize(value,
|
||||
specifiedType: const FullType(double)) as double;
|
||||
break;
|
||||
case 'credit_date':
|
||||
result.creditDate = serializers.deserialize(value,
|
||||
specifiedType: const FullType(String)) as String;
|
||||
break;
|
||||
case 'credit_number':
|
||||
result.creditNumber = serializers.deserialize(value,
|
||||
specifiedType: const FullType(String)) as String;
|
||||
break;
|
||||
case 'private_notes':
|
||||
result.privateNotes = serializers.deserialize(value,
|
||||
specifiedType: const FullType(String)) as String;
|
||||
break;
|
||||
case 'public_notes':
|
||||
result.publicNotes = serializers.deserialize(value,
|
||||
specifiedType: const FullType(String)) as String;
|
||||
break;
|
||||
case 'client_id':
|
||||
result.clientId = 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(String)) as String;
|
||||
break;
|
||||
case 'id':
|
||||
result.id = serializers.deserialize(value,
|
||||
specifiedType: const FullType(String)) as String;
|
||||
specifiedType: const FullType(InvoiceEntity)) as InvoiceEntity);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -273,7 +100,7 @@ class _$CreditEntitySerializer implements StructuredSerializer<CreditEntity> {
|
|||
|
||||
class _$CreditListResponse extends CreditListResponse {
|
||||
@override
|
||||
final BuiltList<CreditEntity> data;
|
||||
final BuiltList<InvoiceEntity> data;
|
||||
|
||||
factory _$CreditListResponse(
|
||||
[void Function(CreditListResponseBuilder) updates]) =>
|
||||
|
|
@ -317,10 +144,10 @@ class CreditListResponseBuilder
|
|||
implements Builder<CreditListResponse, CreditListResponseBuilder> {
|
||||
_$CreditListResponse _$v;
|
||||
|
||||
ListBuilder<CreditEntity> _data;
|
||||
ListBuilder<CreditEntity> get data =>
|
||||
_$this._data ??= new ListBuilder<CreditEntity>();
|
||||
set data(ListBuilder<CreditEntity> data) => _$this._data = data;
|
||||
ListBuilder<InvoiceEntity> _data;
|
||||
ListBuilder<InvoiceEntity> get data =>
|
||||
_$this._data ??= new ListBuilder<InvoiceEntity>();
|
||||
set data(ListBuilder<InvoiceEntity> data) => _$this._data = data;
|
||||
|
||||
CreditListResponseBuilder();
|
||||
|
||||
|
|
@ -368,7 +195,7 @@ class CreditListResponseBuilder
|
|||
|
||||
class _$CreditItemResponse extends CreditItemResponse {
|
||||
@override
|
||||
final CreditEntity data;
|
||||
final InvoiceEntity data;
|
||||
|
||||
factory _$CreditItemResponse(
|
||||
[void Function(CreditItemResponseBuilder) updates]) =>
|
||||
|
|
@ -412,9 +239,9 @@ class CreditItemResponseBuilder
|
|||
implements Builder<CreditItemResponse, CreditItemResponseBuilder> {
|
||||
_$CreditItemResponse _$v;
|
||||
|
||||
CreditEntityBuilder _data;
|
||||
CreditEntityBuilder get data => _$this._data ??= new CreditEntityBuilder();
|
||||
set data(CreditEntityBuilder data) => _$this._data = data;
|
||||
InvoiceEntityBuilder _data;
|
||||
InvoiceEntityBuilder get data => _$this._data ??= new InvoiceEntityBuilder();
|
||||
set data(InvoiceEntityBuilder data) => _$this._data = data;
|
||||
|
||||
CreditItemResponseBuilder();
|
||||
|
||||
|
|
@ -460,308 +287,4 @@ class CreditItemResponseBuilder
|
|||
}
|
||||
}
|
||||
|
||||
class _$CreditEntity extends CreditEntity {
|
||||
@override
|
||||
final double amount;
|
||||
@override
|
||||
final double balance;
|
||||
@override
|
||||
final String creditDate;
|
||||
@override
|
||||
final String creditNumber;
|
||||
@override
|
||||
final String privateNotes;
|
||||
@override
|
||||
final String publicNotes;
|
||||
@override
|
||||
final int clientId;
|
||||
@override
|
||||
final bool isChanged;
|
||||
@override
|
||||
final int createdAt;
|
||||
@override
|
||||
final int updatedAt;
|
||||
@override
|
||||
final int archivedAt;
|
||||
@override
|
||||
final bool isDeleted;
|
||||
@override
|
||||
final String createdUserId;
|
||||
@override
|
||||
final String assignedUserId;
|
||||
@override
|
||||
final String subEntityType;
|
||||
@override
|
||||
final String id;
|
||||
|
||||
factory _$CreditEntity([void Function(CreditEntityBuilder) updates]) =>
|
||||
(new CreditEntityBuilder()..update(updates)).build();
|
||||
|
||||
_$CreditEntity._(
|
||||
{this.amount,
|
||||
this.balance,
|
||||
this.creditDate,
|
||||
this.creditNumber,
|
||||
this.privateNotes,
|
||||
this.publicNotes,
|
||||
this.clientId,
|
||||
this.isChanged,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
this.archivedAt,
|
||||
this.isDeleted,
|
||||
this.createdUserId,
|
||||
this.assignedUserId,
|
||||
this.subEntityType,
|
||||
this.id})
|
||||
: super._() {
|
||||
if (amount == null) {
|
||||
throw new BuiltValueNullFieldError('CreditEntity', 'amount');
|
||||
}
|
||||
if (balance == null) {
|
||||
throw new BuiltValueNullFieldError('CreditEntity', 'balance');
|
||||
}
|
||||
if (creditDate == null) {
|
||||
throw new BuiltValueNullFieldError('CreditEntity', 'creditDate');
|
||||
}
|
||||
if (creditNumber == null) {
|
||||
throw new BuiltValueNullFieldError('CreditEntity', 'creditNumber');
|
||||
}
|
||||
if (privateNotes == null) {
|
||||
throw new BuiltValueNullFieldError('CreditEntity', 'privateNotes');
|
||||
}
|
||||
if (publicNotes == null) {
|
||||
throw new BuiltValueNullFieldError('CreditEntity', 'publicNotes');
|
||||
}
|
||||
if (clientId == null) {
|
||||
throw new BuiltValueNullFieldError('CreditEntity', 'clientId');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
CreditEntity rebuild(void Function(CreditEntityBuilder) updates) =>
|
||||
(toBuilder()..update(updates)).build();
|
||||
|
||||
@override
|
||||
CreditEntityBuilder toBuilder() => new CreditEntityBuilder()..replace(this);
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(other, this)) return true;
|
||||
return other is CreditEntity &&
|
||||
amount == other.amount &&
|
||||
balance == other.balance &&
|
||||
creditDate == other.creditDate &&
|
||||
creditNumber == other.creditNumber &&
|
||||
privateNotes == other.privateNotes &&
|
||||
publicNotes == other.publicNotes &&
|
||||
clientId == other.clientId &&
|
||||
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;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return $jf($jc(
|
||||
$jc(
|
||||
$jc(
|
||||
$jc(
|
||||
$jc(
|
||||
$jc(
|
||||
$jc(
|
||||
$jc(
|
||||
$jc(
|
||||
$jc(
|
||||
$jc(
|
||||
$jc(
|
||||
$jc(
|
||||
$jc(
|
||||
$jc(
|
||||
$jc(
|
||||
0,
|
||||
amount
|
||||
.hashCode),
|
||||
balance
|
||||
.hashCode),
|
||||
creditDate
|
||||
.hashCode),
|
||||
creditNumber.hashCode),
|
||||
privateNotes.hashCode),
|
||||
publicNotes.hashCode),
|
||||
clientId.hashCode),
|
||||
isChanged.hashCode),
|
||||
createdAt.hashCode),
|
||||
updatedAt.hashCode),
|
||||
archivedAt.hashCode),
|
||||
isDeleted.hashCode),
|
||||
createdUserId.hashCode),
|
||||
assignedUserId.hashCode),
|
||||
subEntityType.hashCode),
|
||||
id.hashCode));
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return (newBuiltValueToStringHelper('CreditEntity')
|
||||
..add('amount', amount)
|
||||
..add('balance', balance)
|
||||
..add('creditDate', creditDate)
|
||||
..add('creditNumber', creditNumber)
|
||||
..add('privateNotes', privateNotes)
|
||||
..add('publicNotes', publicNotes)
|
||||
..add('clientId', clientId)
|
||||
..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 CreditEntityBuilder
|
||||
implements Builder<CreditEntity, CreditEntityBuilder> {
|
||||
_$CreditEntity _$v;
|
||||
|
||||
double _amount;
|
||||
double get amount => _$this._amount;
|
||||
set amount(double amount) => _$this._amount = amount;
|
||||
|
||||
double _balance;
|
||||
double get balance => _$this._balance;
|
||||
set balance(double balance) => _$this._balance = balance;
|
||||
|
||||
String _creditDate;
|
||||
String get creditDate => _$this._creditDate;
|
||||
set creditDate(String creditDate) => _$this._creditDate = creditDate;
|
||||
|
||||
String _creditNumber;
|
||||
String get creditNumber => _$this._creditNumber;
|
||||
set creditNumber(String creditNumber) => _$this._creditNumber = creditNumber;
|
||||
|
||||
String _privateNotes;
|
||||
String get privateNotes => _$this._privateNotes;
|
||||
set privateNotes(String privateNotes) => _$this._privateNotes = privateNotes;
|
||||
|
||||
String _publicNotes;
|
||||
String get publicNotes => _$this._publicNotes;
|
||||
set publicNotes(String publicNotes) => _$this._publicNotes = publicNotes;
|
||||
|
||||
int _clientId;
|
||||
int get clientId => _$this._clientId;
|
||||
set clientId(int clientId) => _$this._clientId = clientId;
|
||||
|
||||
bool _isChanged;
|
||||
bool get isChanged => _$this._isChanged;
|
||||
set isChanged(bool isChanged) => _$this._isChanged = isChanged;
|
||||
|
||||
int _createdAt;
|
||||
int get createdAt => _$this._createdAt;
|
||||
set createdAt(int createdAt) => _$this._createdAt = createdAt;
|
||||
|
||||
int _updatedAt;
|
||||
int get updatedAt => _$this._updatedAt;
|
||||
set updatedAt(int updatedAt) => _$this._updatedAt = updatedAt;
|
||||
|
||||
int _archivedAt;
|
||||
int get archivedAt => _$this._archivedAt;
|
||||
set archivedAt(int archivedAt) => _$this._archivedAt = archivedAt;
|
||||
|
||||
bool _isDeleted;
|
||||
bool get isDeleted => _$this._isDeleted;
|
||||
set isDeleted(bool isDeleted) => _$this._isDeleted = isDeleted;
|
||||
|
||||
String _createdUserId;
|
||||
String get createdUserId => _$this._createdUserId;
|
||||
set createdUserId(String createdUserId) =>
|
||||
_$this._createdUserId = createdUserId;
|
||||
|
||||
String _assignedUserId;
|
||||
String get assignedUserId => _$this._assignedUserId;
|
||||
set assignedUserId(String assignedUserId) =>
|
||||
_$this._assignedUserId = assignedUserId;
|
||||
|
||||
String _subEntityType;
|
||||
String get subEntityType => _$this._subEntityType;
|
||||
set subEntityType(String subEntityType) =>
|
||||
_$this._subEntityType = subEntityType;
|
||||
|
||||
String _id;
|
||||
String get id => _$this._id;
|
||||
set id(String id) => _$this._id = id;
|
||||
|
||||
CreditEntityBuilder();
|
||||
|
||||
CreditEntityBuilder get _$this {
|
||||
if (_$v != null) {
|
||||
_amount = _$v.amount;
|
||||
_balance = _$v.balance;
|
||||
_creditDate = _$v.creditDate;
|
||||
_creditNumber = _$v.creditNumber;
|
||||
_privateNotes = _$v.privateNotes;
|
||||
_publicNotes = _$v.publicNotes;
|
||||
_clientId = _$v.clientId;
|
||||
_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(CreditEntity other) {
|
||||
if (other == null) {
|
||||
throw new ArgumentError.notNull('other');
|
||||
}
|
||||
_$v = other as _$CreditEntity;
|
||||
}
|
||||
|
||||
@override
|
||||
void update(void Function(CreditEntityBuilder) updates) {
|
||||
if (updates != null) updates(this);
|
||||
}
|
||||
|
||||
@override
|
||||
_$CreditEntity build() {
|
||||
final _$result = _$v ??
|
||||
new _$CreditEntity._(
|
||||
amount: amount,
|
||||
balance: balance,
|
||||
creditDate: creditDate,
|
||||
creditNumber: creditNumber,
|
||||
privateNotes: privateNotes,
|
||||
publicNotes: publicNotes,
|
||||
clientId: clientId,
|
||||
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
|
||||
|
|
|
|||
|
|
@ -484,7 +484,7 @@ abstract class ActivityEntity
|
|||
ClientEntity client,
|
||||
InvoiceEntity invoice,
|
||||
PaymentEntity payment,
|
||||
CreditEntity credit,
|
||||
InvoiceEntity credit,
|
||||
InvoiceEntity quote,
|
||||
TaskEntity task,
|
||||
ExpenseEntity expense,
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@ 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/data/models/credit_model.dart';
|
||||
import 'package:invoiceninja_flutter/redux/credit/credit_state.dart';
|
||||
|
||||
import 'package:invoiceninja_flutter/data/models/user_model.dart';
|
||||
import 'package:invoiceninja_flutter/redux/user/user_state.dart';
|
||||
import 'package:invoiceninja_flutter/redux/tax_rate/tax_rate_state.dart';
|
||||
|
|
@ -109,6 +112,8 @@ part 'serializers.g.dart';
|
|||
TaxRateItemResponse,
|
||||
TaxRateListResponse,
|
||||
// STARTER: serializers - do not remove comment
|
||||
InvoiceEntity,
|
||||
|
||||
PaymentableEntity,
|
||||
UserEntity,
|
||||
UserListResponse,
|
||||
|
|
|
|||
|
|
@ -29,9 +29,10 @@ Serializers _$serializers = (new Serializers().toBuilder()
|
|||
..add(CountryEntity.serializer)
|
||||
..add(CountryItemResponse.serializer)
|
||||
..add(CountryListResponse.serializer)
|
||||
..add(CreditEntity.serializer)
|
||||
..add(CreditItemResponse.serializer)
|
||||
..add(CreditListResponse.serializer)
|
||||
..add(CreditState.serializer)
|
||||
..add(CreditUIState.serializer)
|
||||
..add(CurrencyEntity.serializer)
|
||||
..add(CurrencyItemResponse.serializer)
|
||||
..add(CurrencyListResponse.serializer)
|
||||
|
|
@ -177,9 +178,6 @@ Serializers _$serializers = (new Serializers().toBuilder()
|
|||
..addBuilderFactory(
|
||||
const FullType(BuiltList, const [const FullType(CountryEntity)]),
|
||||
() => new ListBuilder<CountryEntity>())
|
||||
..addBuilderFactory(
|
||||
const FullType(BuiltList, const [const FullType(CreditEntity)]),
|
||||
() => new ListBuilder<CreditEntity>())
|
||||
..addBuilderFactory(
|
||||
const FullType(BuiltList, const [const FullType(CurrencyEntity)]),
|
||||
() => new ListBuilder<CurrencyEntity>())
|
||||
|
|
@ -343,6 +341,7 @@ Serializers _$serializers = (new Serializers().toBuilder()
|
|||
() => new ListBuilder<InvoiceDesignEntity>())
|
||||
..addBuilderFactory(
|
||||
const FullType(BuiltList, const [const FullType(InvoiceEntity)]), () => new ListBuilder<InvoiceEntity>())
|
||||
..addBuilderFactory(const FullType(BuiltList, const [const FullType(InvoiceEntity)]), () => new ListBuilder<InvoiceEntity>())
|
||||
..addBuilderFactory(const FullType(BuiltList, const [const FullType(InvoiceItemEntity)]), () => new ListBuilder<InvoiceItemEntity>())
|
||||
..addBuilderFactory(const FullType(BuiltList, const [const FullType(InvitationEntity)]), () => new ListBuilder<InvitationEntity>())
|
||||
..addBuilderFactory(const FullType(BuiltList, const [const FullType(LanguageEntity)]), () => new ListBuilder<LanguageEntity>())
|
||||
|
|
@ -395,6 +394,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(InvoiceEntity)]), () => new MapBuilder<String, InvoiceEntity>())
|
||||
..addBuilderFactory(const FullType(BuiltList, const [const FullType(String)]), () => new ListBuilder<String>())
|
||||
..addBuilderFactory(const FullType(BuiltMap, const [const FullType(String), const FullType(InvoiceEntity)]), () => new MapBuilder<String, InvoiceEntity>())
|
||||
..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(ProductEntity)]), () => new MapBuilder<String, ProductEntity>())
|
||||
|
|
|
|||
|
|
@ -0,0 +1,84 @@
|
|||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:core';
|
||||
import 'package:invoiceninja_flutter/.env.dart';
|
||||
import 'package:built_collection/built_collection.dart';
|
||||
import 'package:invoiceninja_flutter/constants.dart';
|
||||
import 'package:invoiceninja_flutter/data/models/serializers.dart';
|
||||
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
|
||||
import 'package:invoiceninja_flutter/data/models/models.dart';
|
||||
import 'package:invoiceninja_flutter/data/web_client.dart';
|
||||
|
||||
class CreditRepository {
|
||||
const CreditRepository({
|
||||
this.webClient = const WebClient(),
|
||||
});
|
||||
|
||||
final WebClient webClient;
|
||||
|
||||
Future<InvoiceEntity> loadItem(
|
||||
Credentials credentials, String entityId) async {
|
||||
final dynamic response = await webClient.get(
|
||||
'${credentials.url}/credits/$entityId', credentials.token);
|
||||
|
||||
final CreditItemResponse creditResponse =
|
||||
serializers.deserializeWith(CreditItemResponse.serializer, response);
|
||||
|
||||
return creditResponse.data;
|
||||
}
|
||||
|
||||
Future<BuiltList<InvoiceEntity>> loadList(
|
||||
Credentials credentials, int updatedAt) async {
|
||||
String url = credentials.url + '/credits?';
|
||||
|
||||
if (updatedAt > 0) {
|
||||
url += '&updated_at=${updatedAt - kUpdatedAtBufferSeconds}';
|
||||
}
|
||||
|
||||
final dynamic response = await webClient.get(url, credentials.token);
|
||||
|
||||
final CreditListResponse creditResponse =
|
||||
serializers.deserializeWith(CreditListResponse.serializer, response);
|
||||
|
||||
return creditResponse.data;
|
||||
}
|
||||
|
||||
Future<List<InvoiceEntity>> bulkAction(
|
||||
Credentials credentials, List<String> ids, EntityAction action) async {
|
||||
var url = credentials.url + '/credits/bulk?';
|
||||
if (action != null) {
|
||||
url += '&action=' + action.toString();
|
||||
}
|
||||
final dynamic response = await webClient.post(url, credentials.token,
|
||||
data: json.encode({'ids': ids}));
|
||||
|
||||
final CreditListResponse invoiceResponse =
|
||||
serializers.deserializeWith(CreditListResponse.serializer, response);
|
||||
|
||||
return invoiceResponse.data.toList();
|
||||
}
|
||||
|
||||
Future<InvoiceEntity> saveData(Credentials credentials, InvoiceEntity credit,
|
||||
[EntityAction action]) async {
|
||||
final data = serializers.serializeWith(InvoiceEntity.serializer, credit);
|
||||
dynamic response;
|
||||
|
||||
if (credit.isNew) {
|
||||
response = await webClient.post(
|
||||
credentials.url + '/credits', credentials.token,
|
||||
data: json.encode(data));
|
||||
} else {
|
||||
var url = credentials.url + '/credits/' + credit.id.toString();
|
||||
if (action != null) {
|
||||
url += '?action=' + action.toString();
|
||||
}
|
||||
response =
|
||||
await webClient.put(url, credentials.token, data: json.encode(data));
|
||||
}
|
||||
|
||||
final CreditItemResponse creditResponse =
|
||||
serializers.deserializeWith(CreditItemResponse.serializer, response);
|
||||
|
||||
return creditResponse.data;
|
||||
}
|
||||
}
|
||||
|
|
@ -49,6 +49,12 @@ import 'package:sentry/sentry.dart';
|
|||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
// STARTER: import - do not remove comment
|
||||
import 'package:invoiceninja_flutter/ui/credit/credit_screen.dart';
|
||||
import 'package:invoiceninja_flutter/ui/credit/edit/credit_edit_vm.dart';
|
||||
import 'package:invoiceninja_flutter/ui/credit/view/credit_view_vm.dart';
|
||||
import 'package:invoiceninja_flutter/redux/credit/credit_actions.dart';
|
||||
import 'package:invoiceninja_flutter/redux/credit/credit_middleware.dart';
|
||||
|
||||
import 'package:invoiceninja_flutter/ui/user/user_screen.dart';
|
||||
import 'package:invoiceninja_flutter/ui/user/edit/user_edit_vm.dart';
|
||||
import 'package:invoiceninja_flutter/ui/user/view/user_view_vm.dart';
|
||||
|
|
@ -94,6 +100,7 @@ void main({bool isTesting = false}) async {
|
|||
..addAll(createStoreSettingsMiddleware())
|
||||
..addAll(createStoreReportsMiddleware())
|
||||
// STARTER: middleware - do not remove comment
|
||||
..addAll(createStoreCreditsMiddleware())
|
||||
..addAll(createStoreUsersMiddleware())
|
||||
..addAll(createStoreTaxRatesMiddleware())
|
||||
..addAll(createStoreCompanyGatewaysMiddleware())
|
||||
|
|
@ -344,6 +351,10 @@ class InvoiceNinjaAppState extends State<InvoiceNinjaApp> {
|
|||
QuoteEditScreen.route: (context) => QuoteEditScreen(),
|
||||
QuoteEmailScreen.route: (context) => QuoteEmailScreen(),
|
||||
// STARTER: routes - do not remove comment
|
||||
CreditScreen.route: (context) => CreditScreen(),
|
||||
CreditViewScreen.route: (context) => CreditViewScreen(),
|
||||
CreditEditScreen.route: (context) => CreditEditScreen(),
|
||||
|
||||
UserScreen.route: (context) => UserScreenBuilder(),
|
||||
UserViewScreen.route: (context) => UserViewScreen(),
|
||||
UserEditScreen.route: (context) => UserEditScreen(),
|
||||
|
|
|
|||
|
|
@ -26,6 +26,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/credit/credit_actions.dart';
|
||||
|
||||
class PersistUI {}
|
||||
|
||||
|
|
@ -230,6 +231,12 @@ void filterEntitiesByType({
|
|||
));
|
||||
break;
|
||||
// STARTER: filter - do not remove comment
|
||||
case EntityType.credit:
|
||||
store.dispatch(FilterCreditsByEntity(
|
||||
entityId: filterEntity.id,
|
||||
entityType: filterEntity.entityType,
|
||||
));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -299,6 +306,9 @@ void viewEntitiesByType({
|
|||
store.dispatch(ViewGroupList(navigator: navigator));
|
||||
break;
|
||||
// STARTER: view list - do not remove comment
|
||||
case EntityType.credit:
|
||||
store.dispatch(ViewCreditList(navigator: navigator));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -423,6 +433,13 @@ void viewEntityById({
|
|||
));
|
||||
break;
|
||||
// STARTER: view - do not remove comment
|
||||
case EntityType.credit:
|
||||
store.dispatch(ViewCredit(
|
||||
creditId: entityId,
|
||||
navigator: navigator,
|
||||
force: force,
|
||||
));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -537,6 +554,13 @@ void createEntityByType(
|
|||
));
|
||||
break;
|
||||
// STARTER: create type - do not remove comment
|
||||
case EntityType.credit:
|
||||
store.dispatch(EditCredit(
|
||||
navigator: navigator,
|
||||
force: force,
|
||||
credit: InvoiceEntity(state: state),
|
||||
));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -668,6 +692,14 @@ void createEntity({
|
|||
));
|
||||
break;
|
||||
// STARTER: create - do not remove comment
|
||||
case EntityType.credit:
|
||||
store.dispatch(EditCredit(
|
||||
navigator: navigator,
|
||||
credit: entity,
|
||||
force: force,
|
||||
completer: completer,
|
||||
));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -850,6 +882,18 @@ void editEntityById(
|
|||
));
|
||||
break;
|
||||
// STARTER: edit - do not remove comment
|
||||
case EntityType.credit:
|
||||
store.dispatch(EditCredit(
|
||||
credit: map[entityId],
|
||||
navigator: navigator,
|
||||
completer: completer ??
|
||||
snackBarCompleter<InvoiceEntity>(
|
||||
context,
|
||||
entity.isNew
|
||||
? localization.createdCredit
|
||||
: localization.updatedCredit),
|
||||
));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -920,5 +964,8 @@ void handleEntitiesActions(
|
|||
handleDocumentAction(context, entities, action);
|
||||
break;
|
||||
// STARTER: actions - do not remove comment
|
||||
case EntityType.credit:
|
||||
handleCreditAction(context, entities, action);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ 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/credit/credit_actions.dart';
|
||||
|
||||
// We create the State reducer by combining many smaller reducers into one!
|
||||
AppState appReducer(AppState state, dynamic action) {
|
||||
|
|
@ -84,6 +85,10 @@ final lastErrorReducer = combineReducers<String>([
|
|||
return '${action.error}';
|
||||
}),
|
||||
// STARTER: errors - do not remove comment
|
||||
TypedReducer<String, LoadCreditsFailure>((state, action) {
|
||||
return '${action.error}';
|
||||
}),
|
||||
|
||||
TypedReducer<String, RefreshDataFailure>((state, action) {
|
||||
return '${action.error}';
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@ 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/credit/credit_state.dart';
|
||||
|
||||
import 'package:invoiceninja_flutter/redux/user/user_state.dart';
|
||||
import 'package:invoiceninja_flutter/redux/tax_rate/tax_rate_state.dart';
|
||||
import 'package:invoiceninja_flutter/redux/company_gateway/company_gateway_state.dart';
|
||||
|
|
@ -160,6 +162,9 @@ abstract class AppState implements Built<AppState, AppStateBuilder> {
|
|||
case EntityType.invoice:
|
||||
return invoiceState.map;
|
||||
// STARTER: states switch map - do not remove comment
|
||||
case EntityType.credit:
|
||||
return creditState.map;
|
||||
|
||||
case EntityType.user:
|
||||
return userState.map;
|
||||
case EntityType.taxRate:
|
||||
|
|
@ -217,6 +222,9 @@ abstract class AppState implements Built<AppState, AppStateBuilder> {
|
|||
case EntityType.invoice:
|
||||
return invoiceState.list;
|
||||
// STARTER: states switch list - do not remove comment
|
||||
case EntityType.credit:
|
||||
return creditState.list;
|
||||
|
||||
case EntityType.user:
|
||||
return userState.list;
|
||||
case EntityType.taxRate:
|
||||
|
|
@ -253,6 +261,9 @@ abstract class AppState implements Built<AppState, AppStateBuilder> {
|
|||
case EntityType.invoice:
|
||||
return invoiceUIState;
|
||||
// STARTER: states switch - do not remove comment
|
||||
case EntityType.credit:
|
||||
return creditUIState;
|
||||
|
||||
case EntityType.user:
|
||||
return userUIState;
|
||||
case EntityType.taxRate:
|
||||
|
|
@ -303,6 +314,10 @@ abstract class AppState implements Built<AppState, AppStateBuilder> {
|
|||
ListUIState get invoiceListState => uiState.invoiceUIState.listUIState;
|
||||
|
||||
// STARTER: state getters - do not remove comment
|
||||
CreditState get creditState => userCompanyState.creditState;
|
||||
ListUIState get creditListState => uiState.creditUIState.listUIState;
|
||||
CreditUIState get creditUIState => uiState.creditUIState;
|
||||
|
||||
UserState get userState => userCompanyState.userState;
|
||||
|
||||
ListUIState get userListState => uiState.userUIState.listUIState;
|
||||
|
|
|
|||
|
|
@ -283,16 +283,6 @@ class FilterClientsByCustom4 implements PersistUI {
|
|||
|
||||
void handleClientAction(
|
||||
BuildContext context, List<BaseEntity> clients, EntityAction action) {
|
||||
assert(
|
||||
[
|
||||
EntityAction.restore,
|
||||
EntityAction.archive,
|
||||
EntityAction.delete,
|
||||
EntityAction.toggleMultiselect
|
||||
].contains(action) ||
|
||||
clients.length <= 1,
|
||||
'Cannot perform this action on more than one client');
|
||||
|
||||
if (clients.isEmpty) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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/credit/credit_reducer.dart';
|
||||
|
||||
import 'package:invoiceninja_flutter/redux/user/user_reducer.dart';
|
||||
import 'package:invoiceninja_flutter/redux/tax_rate/tax_rate_reducer.dart';
|
||||
import 'package:invoiceninja_flutter/redux/company_gateway/company_gateway_reducer.dart';
|
||||
|
|
@ -38,6 +40,7 @@ UserCompanyState companyReducer(UserCompanyState state, dynamic action) {
|
|||
..vendorState.replace(vendorsReducer(state.vendorState, action))
|
||||
..taskState.replace(tasksReducer(state.taskState, action))
|
||||
// STARTER: reducer - do not remove comment
|
||||
..creditState.replace(creditsReducer(state.creditState, action))
|
||||
..userState.replace(usersReducer(state.userState, action))
|
||||
..taxRateState.replace(taxRatesReducer(state.taxRateState, action))
|
||||
..companyGatewayState
|
||||
|
|
|
|||
|
|
@ -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/credit/credit_state.dart';
|
||||
|
||||
import 'package:invoiceninja_flutter/redux/user/user_state.dart';
|
||||
import 'package:invoiceninja_flutter/redux/tax_rate/tax_rate_state.dart';
|
||||
import 'package:invoiceninja_flutter/redux/company_gateway/company_gateway_state.dart';
|
||||
|
|
@ -37,6 +39,8 @@ abstract class UserCompanyState
|
|||
paymentState: PaymentState(),
|
||||
quoteState: QuoteState(),
|
||||
// STARTER: constructor - do not remove comment
|
||||
creditState: CreditState(),
|
||||
|
||||
userState: UserState(),
|
||||
taxRateState: TaxRateState(),
|
||||
companyGatewayState: CompanyGatewayState(),
|
||||
|
|
@ -70,6 +74,8 @@ abstract class UserCompanyState
|
|||
QuoteState get quoteState;
|
||||
|
||||
// STARTER: fields - do not remove comment
|
||||
CreditState get creditState;
|
||||
|
||||
UserState get userState;
|
||||
|
||||
TaxRateState get taxRateState;
|
||||
|
|
|
|||
|
|
@ -52,6 +52,9 @@ class _$UserCompanyStateSerializer
|
|||
'quoteState',
|
||||
serializers.serialize(object.quoteState,
|
||||
specifiedType: const FullType(QuoteState)),
|
||||
'creditState',
|
||||
serializers.serialize(object.creditState,
|
||||
specifiedType: const FullType(CreditState)),
|
||||
'userState',
|
||||
serializers.serialize(object.userState,
|
||||
specifiedType: const FullType(UserState)),
|
||||
|
|
@ -131,6 +134,10 @@ class _$UserCompanyStateSerializer
|
|||
result.quoteState.replace(serializers.deserialize(value,
|
||||
specifiedType: const FullType(QuoteState)) as QuoteState);
|
||||
break;
|
||||
case 'creditState':
|
||||
result.creditState.replace(serializers.deserialize(value,
|
||||
specifiedType: const FullType(CreditState)) as CreditState);
|
||||
break;
|
||||
case 'userState':
|
||||
result.userState.replace(serializers.deserialize(value,
|
||||
specifiedType: const FullType(UserState)) as UserState);
|
||||
|
|
@ -314,6 +321,8 @@ class _$UserCompanyState extends UserCompanyState {
|
|||
@override
|
||||
final QuoteState quoteState;
|
||||
@override
|
||||
final CreditState creditState;
|
||||
@override
|
||||
final UserState userState;
|
||||
@override
|
||||
final TaxRateState taxRateState;
|
||||
|
|
@ -338,6 +347,7 @@ class _$UserCompanyState extends UserCompanyState {
|
|||
this.projectState,
|
||||
this.paymentState,
|
||||
this.quoteState,
|
||||
this.creditState,
|
||||
this.userState,
|
||||
this.taxRateState,
|
||||
this.companyGatewayState,
|
||||
|
|
@ -373,6 +383,9 @@ class _$UserCompanyState extends UserCompanyState {
|
|||
if (quoteState == null) {
|
||||
throw new BuiltValueNullFieldError('UserCompanyState', 'quoteState');
|
||||
}
|
||||
if (creditState == null) {
|
||||
throw new BuiltValueNullFieldError('UserCompanyState', 'creditState');
|
||||
}
|
||||
if (userState == null) {
|
||||
throw new BuiltValueNullFieldError('UserCompanyState', 'userState');
|
||||
}
|
||||
|
|
@ -411,6 +424,7 @@ class _$UserCompanyState extends UserCompanyState {
|
|||
projectState == other.projectState &&
|
||||
paymentState == other.paymentState &&
|
||||
quoteState == other.quoteState &&
|
||||
creditState == other.creditState &&
|
||||
userState == other.userState &&
|
||||
taxRateState == other.taxRateState &&
|
||||
companyGatewayState == other.companyGatewayState &&
|
||||
|
|
@ -434,20 +448,23 @@ class _$UserCompanyState extends UserCompanyState {
|
|||
$jc(
|
||||
$jc(
|
||||
$jc(
|
||||
0,
|
||||
userCompany
|
||||
$jc(
|
||||
0,
|
||||
userCompany
|
||||
.hashCode),
|
||||
documentState
|
||||
.hashCode),
|
||||
documentState
|
||||
productState
|
||||
.hashCode),
|
||||
productState.hashCode),
|
||||
clientState.hashCode),
|
||||
invoiceState.hashCode),
|
||||
expenseState.hashCode),
|
||||
vendorState.hashCode),
|
||||
taskState.hashCode),
|
||||
projectState.hashCode),
|
||||
paymentState.hashCode),
|
||||
quoteState.hashCode),
|
||||
clientState.hashCode),
|
||||
invoiceState.hashCode),
|
||||
expenseState.hashCode),
|
||||
vendorState.hashCode),
|
||||
taskState.hashCode),
|
||||
projectState.hashCode),
|
||||
paymentState.hashCode),
|
||||
quoteState.hashCode),
|
||||
creditState.hashCode),
|
||||
userState.hashCode),
|
||||
taxRateState.hashCode),
|
||||
companyGatewayState.hashCode),
|
||||
|
|
@ -468,6 +485,7 @@ class _$UserCompanyState extends UserCompanyState {
|
|||
..add('projectState', projectState)
|
||||
..add('paymentState', paymentState)
|
||||
..add('quoteState', quoteState)
|
||||
..add('creditState', creditState)
|
||||
..add('userState', userState)
|
||||
..add('taxRateState', taxRateState)
|
||||
..add('companyGatewayState', companyGatewayState)
|
||||
|
|
@ -545,6 +563,12 @@ class UserCompanyStateBuilder
|
|||
set quoteState(QuoteStateBuilder quoteState) =>
|
||||
_$this._quoteState = quoteState;
|
||||
|
||||
CreditStateBuilder _creditState;
|
||||
CreditStateBuilder get creditState =>
|
||||
_$this._creditState ??= new CreditStateBuilder();
|
||||
set creditState(CreditStateBuilder creditState) =>
|
||||
_$this._creditState = creditState;
|
||||
|
||||
UserStateBuilder _userState;
|
||||
UserStateBuilder get userState =>
|
||||
_$this._userState ??= new UserStateBuilder();
|
||||
|
|
@ -583,6 +607,7 @@ class UserCompanyStateBuilder
|
|||
_projectState = _$v.projectState?.toBuilder();
|
||||
_paymentState = _$v.paymentState?.toBuilder();
|
||||
_quoteState = _$v.quoteState?.toBuilder();
|
||||
_creditState = _$v.creditState?.toBuilder();
|
||||
_userState = _$v.userState?.toBuilder();
|
||||
_taxRateState = _$v.taxRateState?.toBuilder();
|
||||
_companyGatewayState = _$v.companyGatewayState?.toBuilder();
|
||||
|
|
@ -622,6 +647,7 @@ class UserCompanyStateBuilder
|
|||
projectState: projectState.build(),
|
||||
paymentState: paymentState.build(),
|
||||
quoteState: quoteState.build(),
|
||||
creditState: creditState.build(),
|
||||
userState: userState.build(),
|
||||
taxRateState: taxRateState.build(),
|
||||
companyGatewayState: companyGatewayState.build(),
|
||||
|
|
@ -651,6 +677,8 @@ class UserCompanyStateBuilder
|
|||
paymentState.build();
|
||||
_$failedField = 'quoteState';
|
||||
quoteState.build();
|
||||
_$failedField = 'creditState';
|
||||
creditState.build();
|
||||
_$failedField = 'userState';
|
||||
userState.build();
|
||||
_$failedField = 'taxRateState';
|
||||
|
|
|
|||
|
|
@ -0,0 +1,335 @@
|
|||
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/constants.dart';
|
||||
import 'package:invoiceninja_flutter/data/models/models.dart';
|
||||
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
|
||||
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
|
||||
import 'package:invoiceninja_flutter/redux/settings/settings_actions.dart';
|
||||
import 'package:invoiceninja_flutter/utils/completers.dart';
|
||||
import 'package:invoiceninja_flutter/utils/localization.dart';
|
||||
import 'package:invoiceninja_flutter/utils/platforms.dart';
|
||||
|
||||
class ViewCreditList extends AbstractNavigatorAction implements PersistUI {
|
||||
ViewCreditList({
|
||||
@required NavigatorState navigator,
|
||||
this.force = false,
|
||||
}) : super(navigator: navigator);
|
||||
|
||||
final bool force;
|
||||
}
|
||||
|
||||
class ViewCredit extends AbstractNavigatorAction
|
||||
implements PersistUI, PersistPrefs {
|
||||
ViewCredit({
|
||||
@required NavigatorState navigator,
|
||||
@required this.creditId,
|
||||
this.force = false,
|
||||
}) : super(navigator: navigator);
|
||||
|
||||
final String creditId;
|
||||
final bool force;
|
||||
}
|
||||
|
||||
class EditCredit extends AbstractNavigatorAction
|
||||
implements PersistUI, PersistPrefs {
|
||||
EditCredit(
|
||||
{@required this.credit,
|
||||
@required NavigatorState navigator,
|
||||
this.completer,
|
||||
this.cancelCompleter,
|
||||
this.force = false})
|
||||
: super(navigator: navigator);
|
||||
|
||||
final InvoiceEntity credit;
|
||||
final Completer completer;
|
||||
final Completer cancelCompleter;
|
||||
final bool force;
|
||||
}
|
||||
|
||||
class UpdateCredit implements PersistUI {
|
||||
UpdateCredit(this.credit);
|
||||
|
||||
final InvoiceEntity credit;
|
||||
}
|
||||
|
||||
class LoadCredit {
|
||||
LoadCredit({this.completer, this.creditId});
|
||||
|
||||
final Completer completer;
|
||||
final String creditId;
|
||||
}
|
||||
|
||||
class LoadCreditActivity {
|
||||
LoadCreditActivity({this.completer, this.creditId});
|
||||
|
||||
final Completer completer;
|
||||
final String creditId;
|
||||
}
|
||||
|
||||
class LoadCredits {
|
||||
LoadCredits({this.completer, this.force = false});
|
||||
|
||||
final Completer completer;
|
||||
final bool force;
|
||||
}
|
||||
|
||||
class LoadCreditRequest implements StartLoading {}
|
||||
|
||||
class LoadCreditFailure implements StopLoading {
|
||||
LoadCreditFailure(this.error);
|
||||
|
||||
final dynamic error;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'LoadCreditFailure{error: $error}';
|
||||
}
|
||||
}
|
||||
|
||||
class LoadCreditSuccess implements StopLoading, PersistData {
|
||||
LoadCreditSuccess(this.credit);
|
||||
|
||||
final InvoiceEntity credit;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'LoadCreditSuccess{credit: $credit}';
|
||||
}
|
||||
}
|
||||
|
||||
class LoadCreditsRequest implements StartLoading {}
|
||||
|
||||
class LoadCreditsFailure implements StopLoading {
|
||||
LoadCreditsFailure(this.error);
|
||||
|
||||
final dynamic error;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'LoadCreditsFailure{error: $error}';
|
||||
}
|
||||
}
|
||||
|
||||
class LoadCreditsSuccess implements StopLoading, PersistData {
|
||||
LoadCreditsSuccess(this.credits);
|
||||
|
||||
final BuiltList<InvoiceEntity> credits;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'LoadCreditsSuccess{credits: $credits}';
|
||||
}
|
||||
}
|
||||
|
||||
class SaveCreditRequest implements StartSaving {
|
||||
SaveCreditRequest({this.completer, this.credit});
|
||||
|
||||
final Completer completer;
|
||||
final InvoiceEntity credit;
|
||||
}
|
||||
|
||||
class SaveCreditSuccess implements StopSaving, PersistData, PersistUI {
|
||||
SaveCreditSuccess(this.credit);
|
||||
|
||||
final InvoiceEntity credit;
|
||||
}
|
||||
|
||||
class AddCreditSuccess implements StopSaving, PersistData, PersistUI {
|
||||
AddCreditSuccess(this.credit);
|
||||
|
||||
final InvoiceEntity credit;
|
||||
}
|
||||
|
||||
class SaveCreditFailure implements StopSaving {
|
||||
SaveCreditFailure(this.error);
|
||||
|
||||
final Object error;
|
||||
}
|
||||
|
||||
class ArchiveCreditsRequest implements StartSaving {
|
||||
ArchiveCreditsRequest(this.completer, this.creditIds);
|
||||
|
||||
final Completer completer;
|
||||
final List<String> creditIds;
|
||||
}
|
||||
|
||||
class ArchiveCreditsSuccess implements StopSaving, PersistData {
|
||||
ArchiveCreditsSuccess(this.credits);
|
||||
|
||||
final List<InvoiceEntity> credits;
|
||||
}
|
||||
|
||||
class ArchiveCreditsFailure implements StopSaving {
|
||||
ArchiveCreditsFailure(this.credits);
|
||||
|
||||
final List<InvoiceEntity> credits;
|
||||
}
|
||||
|
||||
class DeleteCreditsRequest implements StartSaving {
|
||||
DeleteCreditsRequest(this.completer, this.creditIds);
|
||||
|
||||
final Completer completer;
|
||||
final List<String> creditIds;
|
||||
}
|
||||
|
||||
class DeleteCreditsSuccess implements StopSaving, PersistData {
|
||||
DeleteCreditsSuccess(this.credits);
|
||||
|
||||
final List<InvoiceEntity> credits;
|
||||
}
|
||||
|
||||
class DeleteCreditsFailure implements StopSaving {
|
||||
DeleteCreditsFailure(this.credits);
|
||||
|
||||
final List<InvoiceEntity> credits;
|
||||
}
|
||||
|
||||
class RestoreCreditsRequest implements StartSaving {
|
||||
RestoreCreditsRequest(this.completer, this.creditIds);
|
||||
|
||||
final Completer completer;
|
||||
final List<String> creditIds;
|
||||
}
|
||||
|
||||
class RestoreCreditsSuccess implements StopSaving, PersistData {
|
||||
RestoreCreditsSuccess(this.credits);
|
||||
|
||||
final List<InvoiceEntity> credits;
|
||||
}
|
||||
|
||||
class RestoreCreditsFailure implements StopSaving {
|
||||
RestoreCreditsFailure(this.credits);
|
||||
|
||||
final List<InvoiceEntity> credits;
|
||||
}
|
||||
|
||||
class FilterCredits implements PersistUI {
|
||||
FilterCredits(this.filter);
|
||||
|
||||
final String filter;
|
||||
}
|
||||
|
||||
class SortCredits implements PersistUI {
|
||||
SortCredits(this.field);
|
||||
|
||||
final String field;
|
||||
}
|
||||
|
||||
class FilterCreditsByState implements PersistUI {
|
||||
FilterCreditsByState(this.state);
|
||||
|
||||
final EntityState state;
|
||||
}
|
||||
|
||||
class FilterCreditsByCustom1 implements PersistUI {
|
||||
FilterCreditsByCustom1(this.value);
|
||||
|
||||
final String value;
|
||||
}
|
||||
|
||||
class FilterCreditsByCustom2 implements PersistUI {
|
||||
FilterCreditsByCustom2(this.value);
|
||||
|
||||
final String value;
|
||||
}
|
||||
|
||||
class FilterCreditsByCustom3 implements PersistUI {
|
||||
FilterCreditsByCustom3(this.value);
|
||||
|
||||
final String value;
|
||||
}
|
||||
|
||||
class FilterCreditsByCustom4 implements PersistUI {
|
||||
FilterCreditsByCustom4(this.value);
|
||||
|
||||
final String value;
|
||||
}
|
||||
|
||||
class FilterCreditsByEntity implements PersistUI {
|
||||
FilterCreditsByEntity({this.entityId, this.entityType});
|
||||
|
||||
final String entityId;
|
||||
final EntityType entityType;
|
||||
}
|
||||
|
||||
void handleCreditAction(
|
||||
BuildContext context, List<BaseEntity> credits, EntityAction action) {
|
||||
if (credits.isEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
final store = StoreProvider.of<AppState>(context);
|
||||
final state = store.state;
|
||||
final CompanyEntity company = state.company;
|
||||
final localization = AppLocalization.of(context);
|
||||
final credit = credits.first as InvoiceEntity;
|
||||
final creditIds = credits.map((credit) => credit.id).toList();
|
||||
|
||||
switch (action) {
|
||||
case EntityAction.edit:
|
||||
editEntity(context: context, entity: credit);
|
||||
break;
|
||||
case EntityAction.restore:
|
||||
store.dispatch(RestoreCreditsRequest(
|
||||
snackBarCompleter<Null>(context, localization.restoredCredit),
|
||||
creditIds));
|
||||
break;
|
||||
case EntityAction.archive:
|
||||
store.dispatch(ArchiveCreditsRequest(
|
||||
snackBarCompleter<Null>(context, localization.archivedCredit),
|
||||
creditIds));
|
||||
break;
|
||||
case EntityAction.delete:
|
||||
store.dispatch(DeleteCreditsRequest(
|
||||
snackBarCompleter<Null>(context, localization.deletedCredit),
|
||||
creditIds));
|
||||
break;
|
||||
case EntityAction.toggleMultiselect:
|
||||
if (!store.state.creditListState.isInMultiselect()) {
|
||||
store.dispatch(StartCreditMultiselect(context: context));
|
||||
}
|
||||
|
||||
if (credits.isEmpty) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (final credit in credits) {
|
||||
if (!store.state.creditListState.isSelected(credit.id)) {
|
||||
store.dispatch(
|
||||
AddToCreditMultiselect(context: context, entity: credit));
|
||||
} else {
|
||||
store.dispatch(
|
||||
RemoveFromCreditMultiselect(context: context, entity: credit));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
class StartCreditMultiselect {
|
||||
StartCreditMultiselect({@required this.context});
|
||||
|
||||
final BuildContext context;
|
||||
}
|
||||
|
||||
class AddToCreditMultiselect {
|
||||
AddToCreditMultiselect({@required this.context, @required this.entity});
|
||||
|
||||
final BuildContext context;
|
||||
final BaseEntity entity;
|
||||
}
|
||||
|
||||
class RemoveFromCreditMultiselect {
|
||||
RemoveFromCreditMultiselect({@required this.context, @required this.entity});
|
||||
|
||||
final BuildContext context;
|
||||
final BaseEntity entity;
|
||||
}
|
||||
|
||||
class ClearCreditMultiselect {
|
||||
ClearCreditMultiselect({@required this.context});
|
||||
|
||||
final BuildContext context;
|
||||
}
|
||||
|
|
@ -0,0 +1,275 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.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/credit/credit_screen.dart';
|
||||
import 'package:invoiceninja_flutter/ui/credit/edit/credit_edit_vm.dart';
|
||||
import 'package:invoiceninja_flutter/ui/credit/view/credit_view_vm.dart';
|
||||
import 'package:invoiceninja_flutter/redux/credit/credit_actions.dart';
|
||||
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
|
||||
import 'package:invoiceninja_flutter/data/repositories/credit_repository.dart';
|
||||
|
||||
List<Middleware<AppState>> createStoreCreditsMiddleware([
|
||||
CreditRepository repository = const CreditRepository(),
|
||||
]) {
|
||||
final viewCreditList = _viewCreditList();
|
||||
final viewCredit = _viewCredit();
|
||||
final editCredit = _editCredit();
|
||||
final loadCredits = _loadCredits(repository);
|
||||
final loadCredit = _loadCredit(repository);
|
||||
final saveCredit = _saveCredit(repository);
|
||||
final archiveCredit = _archiveCredit(repository);
|
||||
final deleteCredit = _deleteCredit(repository);
|
||||
final restoreCredit = _restoreCredit(repository);
|
||||
|
||||
return [
|
||||
TypedMiddleware<AppState, ViewCreditList>(viewCreditList),
|
||||
TypedMiddleware<AppState, ViewCredit>(viewCredit),
|
||||
TypedMiddleware<AppState, EditCredit>(editCredit),
|
||||
TypedMiddleware<AppState, LoadCredits>(loadCredits),
|
||||
TypedMiddleware<AppState, LoadCredit>(loadCredit),
|
||||
TypedMiddleware<AppState, SaveCreditRequest>(saveCredit),
|
||||
TypedMiddleware<AppState, ArchiveCreditsRequest>(archiveCredit),
|
||||
TypedMiddleware<AppState, DeleteCreditsRequest>(deleteCredit),
|
||||
TypedMiddleware<AppState, RestoreCreditsRequest>(restoreCredit),
|
||||
];
|
||||
}
|
||||
|
||||
Middleware<AppState> _editCredit() {
|
||||
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
|
||||
final action = dynamicAction as EditCredit;
|
||||
|
||||
if (!action.force &&
|
||||
hasChanges(store: store, context: action.context, action: action)) {
|
||||
return;
|
||||
}
|
||||
|
||||
next(action);
|
||||
|
||||
store.dispatch(UpdateCurrentRoute(CreditEditScreen.route));
|
||||
|
||||
if (isMobile(action.context)) {
|
||||
action.navigator.pushNamed(CreditEditScreen.route);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Middleware<AppState> _viewCredit() {
|
||||
return (Store<AppState> store, dynamic dynamicAction,
|
||||
NextDispatcher next) async {
|
||||
final action = dynamicAction as ViewCredit;
|
||||
|
||||
if (!action.force &&
|
||||
hasChanges(store: store, context: action.context, action: action)) {
|
||||
return;
|
||||
}
|
||||
|
||||
next(action);
|
||||
|
||||
store.dispatch(UpdateCurrentRoute(CreditViewScreen.route));
|
||||
|
||||
if (isMobile(action.context)) {
|
||||
Navigator.of(action.context).pushNamed(CreditViewScreen.route);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Middleware<AppState> _viewCreditList() {
|
||||
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
|
||||
final action = dynamicAction as ViewCreditList;
|
||||
|
||||
if (!action.force &&
|
||||
hasChanges(store: store, context: action.context, action: action)) {
|
||||
return;
|
||||
}
|
||||
|
||||
next(action);
|
||||
|
||||
if (store.state.creditState.isStale) {
|
||||
store.dispatch(LoadCredits());
|
||||
}
|
||||
|
||||
store.dispatch(UpdateCurrentRoute(CreditScreen.route));
|
||||
|
||||
if (isMobile(action.context)) {
|
||||
Navigator.of(action.context).pushNamedAndRemoveUntil(
|
||||
CreditScreen.route, (Route<dynamic> route) => false);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Middleware<AppState> _archiveCredit(CreditRepository repository) {
|
||||
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
|
||||
final action = dynamicAction as ArchiveCreditsRequest;
|
||||
final prevCredits =
|
||||
action.creditIds.map((id) => store.state.creditState.map[id]).toList();
|
||||
repository
|
||||
.bulkAction(
|
||||
store.state.credentials, action.creditIds, EntityAction.archive)
|
||||
.then((List<InvoiceEntity> credits) {
|
||||
store.dispatch(ArchiveCreditsSuccess(credits));
|
||||
if (action.completer != null) {
|
||||
action.completer.complete(null);
|
||||
}
|
||||
}).catchError((Object error) {
|
||||
print(error);
|
||||
store.dispatch(ArchiveCreditsFailure(prevCredits));
|
||||
if (action.completer != null) {
|
||||
action.completer.completeError(error);
|
||||
}
|
||||
});
|
||||
|
||||
next(action);
|
||||
};
|
||||
}
|
||||
|
||||
Middleware<AppState> _deleteCredit(CreditRepository repository) {
|
||||
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
|
||||
final action = dynamicAction as DeleteCreditsRequest;
|
||||
final prevCredits =
|
||||
action.creditIds.map((id) => store.state.creditState.map[id]).toList();
|
||||
repository
|
||||
.bulkAction(
|
||||
store.state.credentials, action.creditIds, EntityAction.delete)
|
||||
.then((List<InvoiceEntity> credits) {
|
||||
store.dispatch(DeleteCreditsSuccess(credits));
|
||||
if (action.completer != null) {
|
||||
action.completer.complete(null);
|
||||
}
|
||||
}).catchError((Object error) {
|
||||
print(error);
|
||||
store.dispatch(DeleteCreditsFailure(prevCredits));
|
||||
if (action.completer != null) {
|
||||
action.completer.completeError(error);
|
||||
}
|
||||
});
|
||||
|
||||
next(action);
|
||||
};
|
||||
}
|
||||
|
||||
Middleware<AppState> _restoreCredit(CreditRepository repository) {
|
||||
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
|
||||
final action = dynamicAction as RestoreCreditsRequest;
|
||||
final prevCredits =
|
||||
action.creditIds.map((id) => store.state.creditState.map[id]).toList();
|
||||
repository
|
||||
.bulkAction(
|
||||
store.state.credentials, action.creditIds, EntityAction.restore)
|
||||
.then((List<InvoiceEntity> credits) {
|
||||
store.dispatch(RestoreCreditsSuccess(credits));
|
||||
if (action.completer != null) {
|
||||
action.completer.complete(null);
|
||||
}
|
||||
}).catchError((Object error) {
|
||||
print(error);
|
||||
store.dispatch(RestoreCreditsFailure(prevCredits));
|
||||
if (action.completer != null) {
|
||||
action.completer.completeError(error);
|
||||
}
|
||||
});
|
||||
|
||||
next(action);
|
||||
};
|
||||
}
|
||||
|
||||
Middleware<AppState> _saveCredit(CreditRepository repository) {
|
||||
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
|
||||
final action = dynamicAction as SaveCreditRequest;
|
||||
repository
|
||||
.saveData(store.state.credentials, action.credit)
|
||||
.then((InvoiceEntity credit) {
|
||||
if (action.credit.isNew) {
|
||||
store.dispatch(AddCreditSuccess(credit));
|
||||
} else {
|
||||
store.dispatch(SaveCreditSuccess(credit));
|
||||
}
|
||||
|
||||
action.completer.complete(credit);
|
||||
|
||||
final creditUIState = store.state.creditUIState;
|
||||
if (creditUIState.saveCompleter != null) {
|
||||
creditUIState.saveCompleter.complete(credit);
|
||||
}
|
||||
}).catchError((Object error) {
|
||||
print(error);
|
||||
store.dispatch(SaveCreditFailure(error));
|
||||
action.completer.completeError(error);
|
||||
});
|
||||
|
||||
next(action);
|
||||
};
|
||||
}
|
||||
|
||||
Middleware<AppState> _loadCredit(CreditRepository repository) {
|
||||
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
|
||||
final action = dynamicAction as LoadCredit;
|
||||
final AppState state = store.state;
|
||||
|
||||
if (state.isLoading) {
|
||||
next(action);
|
||||
return;
|
||||
}
|
||||
|
||||
store.dispatch(LoadCreditRequest());
|
||||
repository.loadItem(state.credentials, action.creditId).then((credit) {
|
||||
store.dispatch(LoadCreditSuccess(credit));
|
||||
|
||||
if (action.completer != null) {
|
||||
action.completer.complete(null);
|
||||
}
|
||||
}).catchError((Object error) {
|
||||
print(error);
|
||||
store.dispatch(LoadCreditFailure(error));
|
||||
if (action.completer != null) {
|
||||
action.completer.completeError(error);
|
||||
}
|
||||
});
|
||||
|
||||
next(action);
|
||||
};
|
||||
}
|
||||
|
||||
Middleware<AppState> _loadCredits(CreditRepository repository) {
|
||||
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
|
||||
final action = dynamicAction as LoadCredits;
|
||||
final AppState state = store.state;
|
||||
|
||||
if (!state.creditState.isStale && !action.force) {
|
||||
next(action);
|
||||
return;
|
||||
}
|
||||
|
||||
if (state.isLoading) {
|
||||
next(action);
|
||||
return;
|
||||
}
|
||||
|
||||
final int updatedAt = (state.creditState.lastUpdated / 1000).round();
|
||||
|
||||
store.dispatch(LoadCreditsRequest());
|
||||
repository.loadList(state.credentials, updatedAt).then((data) {
|
||||
store.dispatch(LoadCreditsSuccess(data));
|
||||
|
||||
if (action.completer != null) {
|
||||
action.completer.complete(null);
|
||||
}
|
||||
/*
|
||||
if (state.productState.isStale) {
|
||||
store.dispatch(LoadProducts());
|
||||
}
|
||||
*/
|
||||
}).catchError((Object error) {
|
||||
print(error);
|
||||
store.dispatch(LoadCreditsFailure(error));
|
||||
if (action.completer != null) {
|
||||
action.completer.completeError(error);
|
||||
}
|
||||
});
|
||||
|
||||
next(action);
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,288 @@
|
|||
import 'package:built_collection/built_collection.dart';
|
||||
import 'package:redux/redux.dart';
|
||||
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
|
||||
import 'package:invoiceninja_flutter/data/models/models.dart';
|
||||
import 'package:invoiceninja_flutter/redux/company/company_actions.dart';
|
||||
import 'package:invoiceninja_flutter/redux/ui/entity_ui_state.dart';
|
||||
import 'package:invoiceninja_flutter/redux/credit/credit_actions.dart';
|
||||
import 'package:invoiceninja_flutter/redux/ui/list_ui_state.dart';
|
||||
import 'package:invoiceninja_flutter/redux/credit/credit_actions.dart';
|
||||
import 'package:invoiceninja_flutter/redux/credit/credit_state.dart';
|
||||
import 'package:invoiceninja_flutter/data/models/entities.dart';
|
||||
|
||||
EntityUIState creditUIReducer(CreditUIState state, dynamic action) {
|
||||
return state.rebuild((b) =>
|
||||
b
|
||||
..listUIState.replace(creditListReducer(state.listUIState, action))
|
||||
..editing.replace(editingReducer(state.editing, action))
|
||||
..selectedId = selectedIdReducer(state.selectedId, action));
|
||||
}
|
||||
|
||||
Reducer<String> selectedIdReducer = combineReducers([
|
||||
TypedReducer<String, ViewCredit>(
|
||||
(String selectedId, dynamic action) => action.creditId),
|
||||
TypedReducer<String, AddCreditSuccess>(
|
||||
(String selectedId, dynamic action) => action.credit.id),
|
||||
TypedReducer<String, SelectCompany>((selectedId, action) => ''),
|
||||
]);
|
||||
|
||||
final editingReducer = combineReducers<InvoiceEntity>([
|
||||
TypedReducer<InvoiceEntity, SaveCreditSuccess>(_updateEditing),
|
||||
TypedReducer<InvoiceEntity, AddCreditSuccess>(_updateEditing),
|
||||
TypedReducer<InvoiceEntity, RestoreCreditsSuccess>((credits, action) {
|
||||
return action.credits[0];
|
||||
}),
|
||||
TypedReducer<InvoiceEntity, ArchiveCreditsSuccess>((credits, action) {
|
||||
return action.credits[0];
|
||||
}),
|
||||
TypedReducer<InvoiceEntity, DeleteCreditsSuccess>((credits, action) {
|
||||
return action.credits[0];
|
||||
}),
|
||||
TypedReducer<InvoiceEntity, EditCredit>(_updateEditing),
|
||||
TypedReducer<InvoiceEntity, UpdateCredit>((credit, action) {
|
||||
return action.credit.rebuild((b) => b..isChanged = true);
|
||||
}),
|
||||
TypedReducer<InvoiceEntity, SelectCompany>(_clearEditing),
|
||||
TypedReducer<InvoiceEntity, DiscardChanges>(_clearEditing),
|
||||
]);
|
||||
|
||||
InvoiceEntity _clearEditing(InvoiceEntity credit, dynamic action) {
|
||||
return InvoiceEntity();
|
||||
}
|
||||
|
||||
InvoiceEntity _updateEditing(InvoiceEntity credit, dynamic action) {
|
||||
return action.credit;
|
||||
}
|
||||
|
||||
|
||||
final creditListReducer = combineReducers<ListUIState>([
|
||||
TypedReducer<ListUIState, SortCredits>(_sortCredits),
|
||||
TypedReducer<ListUIState, FilterCreditsByState>(_filterCreditsByState),
|
||||
TypedReducer<ListUIState, FilterCredits>(_filterCredits),
|
||||
TypedReducer<ListUIState, FilterCreditsByCustom1>(_filterCreditsByCustom1),
|
||||
TypedReducer<ListUIState, FilterCreditsByCustom2>(_filterCreditsByCustom2),
|
||||
TypedReducer<ListUIState, FilterCreditsByEntity>(_filterCreditsByClient),
|
||||
TypedReducer<ListUIState, StartCreditMultiselect>(_startListMultiselect),
|
||||
TypedReducer<ListUIState, AddToCreditMultiselect>(_addToListMultiselect),
|
||||
TypedReducer<ListUIState, RemoveFromCreditMultiselect>(
|
||||
_removeFromListMultiselect),
|
||||
TypedReducer<ListUIState, ClearCreditMultiselect>(_clearListMultiselect),
|
||||
]);
|
||||
|
||||
ListUIState _filterCreditsByClient(ListUIState creditListState,
|
||||
FilterCreditsByEntity action) {
|
||||
return creditListState.rebuild((b) =>
|
||||
b
|
||||
..filterEntityId = action.entityId
|
||||
..filterEntityType = action.entityType);
|
||||
}
|
||||
|
||||
ListUIState _filterCreditsByCustom1(ListUIState creditListState,
|
||||
FilterCreditsByCustom1 action) {
|
||||
if (creditListState.custom1Filters.contains(action.value)) {
|
||||
return creditListState
|
||||
.rebuild((b) => b..custom1Filters.remove(action.value));
|
||||
} else {
|
||||
return creditListState.rebuild((b) => b..custom1Filters.add(action.value));
|
||||
}
|
||||
}
|
||||
|
||||
ListUIState _filterCreditsByCustom2(ListUIState creditListState,
|
||||
FilterCreditsByCustom2 action) {
|
||||
if (creditListState.custom2Filters.contains(action.value)) {
|
||||
return creditListState
|
||||
.rebuild((b) => b..custom2Filters.remove(action.value));
|
||||
} else {
|
||||
return creditListState.rebuild((b) => b..custom2Filters.add(action.value));
|
||||
}
|
||||
}
|
||||
|
||||
ListUIState _filterCreditsByState(ListUIState creditListState,
|
||||
FilterCreditsByState action) {
|
||||
if (creditListState.stateFilters.contains(action.state)) {
|
||||
return creditListState.rebuild((b) => b..stateFilters.remove(action.state));
|
||||
} else {
|
||||
return creditListState.rebuild((b) => b..stateFilters.add(action.state));
|
||||
}
|
||||
}
|
||||
|
||||
ListUIState _filterCredits(ListUIState creditListState, FilterCredits action) {
|
||||
return creditListState.rebuild((b) =>
|
||||
b
|
||||
..filter = action.filter
|
||||
..filterClearedAt = action.filter == null
|
||||
? DateTime
|
||||
.now()
|
||||
.millisecondsSinceEpoch
|
||||
: creditListState.filterClearedAt);
|
||||
}
|
||||
|
||||
ListUIState _sortCredits(ListUIState creditListState, SortCredits action) {
|
||||
return creditListState.rebuild((b) =>
|
||||
b
|
||||
..sortAscending = b.sortField != action.field || !b.sortAscending
|
||||
..sortField = action.field);
|
||||
}
|
||||
|
||||
ListUIState _startListMultiselect(ListUIState productListState,
|
||||
StartCreditMultiselect action) {
|
||||
return productListState.rebuild((b) => b..selectedIds = ListBuilder());
|
||||
}
|
||||
|
||||
ListUIState _addToListMultiselect(ListUIState productListState,
|
||||
AddToCreditMultiselect action) {
|
||||
return productListState
|
||||
.rebuild((b) => b..selectedIds.add(action.entity.id));
|
||||
}
|
||||
|
||||
ListUIState _removeFromListMultiselect(ListUIState productListState,
|
||||
RemoveFromCreditMultiselect action) {
|
||||
return productListState
|
||||
.rebuild((b) => b..selectedIds.remove(action.entity.id));
|
||||
}
|
||||
|
||||
ListUIState _clearListMultiselect(ListUIState productListState,
|
||||
ClearCreditMultiselect action) {
|
||||
return productListState.rebuild((b) => b..selectedIds = null);
|
||||
}
|
||||
|
||||
final creditsReducer = combineReducers<CreditState>([
|
||||
TypedReducer<CreditState, SaveCreditSuccess>(_updateCredit),
|
||||
TypedReducer<CreditState, AddCreditSuccess>(_addCredit),
|
||||
TypedReducer<CreditState, LoadCreditsSuccess>(_setLoadedCredits),
|
||||
TypedReducer<CreditState, LoadCreditSuccess>(_setLoadedCredit),
|
||||
TypedReducer<CreditState, ArchiveCreditsRequest>(_archiveCreditRequest),
|
||||
TypedReducer<CreditState, ArchiveCreditsSuccess>(_archiveCreditSuccess),
|
||||
TypedReducer<CreditState, ArchiveCreditsFailure>(_archiveCreditFailure),
|
||||
TypedReducer<CreditState, DeleteCreditsRequest>(_deleteCreditRequest),
|
||||
TypedReducer<CreditState, DeleteCreditsSuccess>(_deleteCreditSuccess),
|
||||
TypedReducer<CreditState, DeleteCreditsFailure>(_deleteCreditFailure),
|
||||
TypedReducer<CreditState, RestoreCreditsRequest>(_restoreCreditRequest),
|
||||
TypedReducer<CreditState, RestoreCreditsSuccess>(_restoreCreditSuccess),
|
||||
TypedReducer<CreditState, RestoreCreditsFailure>(_restoreCreditFailure),
|
||||
]);
|
||||
|
||||
CreditState _archiveCreditRequest(
|
||||
CreditState creditState, ArchiveCreditsRequest action) {
|
||||
final credits = action.creditIds.map((id) => creditState.map[id]).toList();
|
||||
|
||||
for (int i = 0; i < credits.length; i++) {
|
||||
credits[i] = credits[i]
|
||||
.rebuild((b) => b..archivedAt = DateTime.now().millisecondsSinceEpoch);
|
||||
}
|
||||
return creditState.rebuild((b) {
|
||||
for (final credit in credits) {
|
||||
b.map[credit.id] = credit;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
CreditState _archiveCreditSuccess(
|
||||
CreditState creditState, ArchiveCreditsSuccess action) {
|
||||
return creditState.rebuild((b) {
|
||||
for (final credit in action.credits) {
|
||||
b.map[credit.id] = credit;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
CreditState _archiveCreditFailure(
|
||||
CreditState creditState, ArchiveCreditsFailure action) {
|
||||
return creditState.rebuild((b) {
|
||||
for (final credit in action.credits) {
|
||||
b.map[credit.id] = credit;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
CreditState _deleteCreditRequest(
|
||||
CreditState creditState, DeleteCreditsRequest action) {
|
||||
final credits = action.creditIds.map((id) => creditState.map[id]).toList();
|
||||
|
||||
for (int i = 0; i < credits.length; i++) {
|
||||
credits[i] = credits[i].rebuild((b) => b
|
||||
..archivedAt = DateTime.now().millisecondsSinceEpoch
|
||||
..isDeleted = true);
|
||||
}
|
||||
return creditState.rebuild((b) {
|
||||
for (final credit in credits) {
|
||||
b.map[credit.id] = credit;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
CreditState _deleteCreditSuccess(
|
||||
CreditState creditState, DeleteCreditsSuccess action) {
|
||||
return creditState.rebuild((b) {
|
||||
for (final credit in action.credits) {
|
||||
b.map[credit.id] = credit;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
CreditState _deleteCreditFailure(
|
||||
CreditState creditState, DeleteCreditsFailure action) {
|
||||
return creditState.rebuild((b) {
|
||||
for (final credit in action.credits) {
|
||||
b.map[credit.id] = credit;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
CreditState _restoreCreditRequest(
|
||||
CreditState creditState, RestoreCreditsRequest action) {
|
||||
final credits = action.creditIds.map((id) => creditState.map[id]).toList();
|
||||
|
||||
for (int i = 0; i < credits.length; i++) {
|
||||
credits[i] = credits[i].rebuild((b) => b
|
||||
..archivedAt = null
|
||||
..isDeleted = false);
|
||||
}
|
||||
return creditState.rebuild((b) {
|
||||
for (final credit in credits) {
|
||||
b.map[credit.id] = credit;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
CreditState _restoreCreditSuccess(
|
||||
CreditState creditState, RestoreCreditSuccess action) {
|
||||
return creditState.rebuild((b) {
|
||||
for (final credit in action.credits) {
|
||||
b.map[credit.id] = credit;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
CreditState _restoreCreditFailure(
|
||||
CreditState creditState, RestoreCreditFailure action) {
|
||||
return creditState.rebuild((b) {
|
||||
for (final credit in action.credits) {
|
||||
b.map[credit.id] = credit;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
CreditState _addCredit(CreditState creditState, AddCreditSuccess action) {
|
||||
return creditState.rebuild((b) =>
|
||||
b
|
||||
..map[action.credit.id] = action.credit
|
||||
..list.add(action.credit.id));
|
||||
}
|
||||
|
||||
CreditState _updateCredit(CreditState creditState, SaveCreditSuccess action) {
|
||||
return creditState.rebuild((b) =>
|
||||
b
|
||||
..map[action.credit.id] = action.credit);
|
||||
}
|
||||
|
||||
CreditState _setLoadedCredit(CreditState creditState,
|
||||
LoadCreditSuccess action) {
|
||||
return creditState.rebuild((b) =>
|
||||
b
|
||||
..map[action.credit.id] = action.credit);
|
||||
}
|
||||
|
||||
CreditState _setLoadedCredits(CreditState creditState,
|
||||
LoadCreditsSuccess action) =>
|
||||
creditState.loadCredits(action.credits);
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
import 'package:invoiceninja_flutter/data/models/credit_model.dart';
|
||||
import 'package:memoize/memoize.dart';
|
||||
import 'package:built_collection/built_collection.dart';
|
||||
import 'package:invoiceninja_flutter/data/models/models.dart';
|
||||
import 'package:invoiceninja_flutter/redux/ui/list_ui_state.dart';
|
||||
|
||||
var memoizedDropdownCreditList = memo3(
|
||||
(BuiltMap<String, InvoiceEntity> creditMap, BuiltList<String> creditList,
|
||||
String clientId) =>
|
||||
dropdownCreditsSelector(creditMap, creditList, clientId));
|
||||
|
||||
List<String> dropdownCreditsSelector(BuiltMap<String, InvoiceEntity> creditMap,
|
||||
BuiltList<String> creditList, String clientId) {
|
||||
final list = creditList.where((creditId) {
|
||||
final credit = creditMap[creditId];
|
||||
/*
|
||||
if (clientId != null && clientId > 0 && credit.clientId != clientId) {
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
return credit.isActive;
|
||||
}).toList();
|
||||
|
||||
list.sort((creditAId, creditBId) {
|
||||
final creditA = creditMap[creditAId];
|
||||
final creditB = creditMap[creditBId];
|
||||
return creditA.compareTo(creditB, CreditFields.name, true);
|
||||
});
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
var memoizedFilteredCreditList = memo3(
|
||||
(BuiltMap<String, InvoiceEntity> creditMap, BuiltList<String> creditList,
|
||||
ListUIState creditListState) =>
|
||||
filteredCreditsSelector(creditMap, creditList, creditListState));
|
||||
|
||||
List<String> filteredCreditsSelector(BuiltMap<String, InvoiceEntity> creditMap,
|
||||
BuiltList<String> creditList, ListUIState creditListState) {
|
||||
final list = creditList.where((creditId) {
|
||||
final credit = creditMap[creditId];
|
||||
if (creditListState.filterEntityId != null &&
|
||||
credit.entityId != creditListState.filterEntityId) {
|
||||
return false;
|
||||
} else {}
|
||||
|
||||
if (!credit.matchesStates(creditListState.stateFilters)) {
|
||||
return false;
|
||||
}
|
||||
if (creditListState.custom1Filters.isNotEmpty &&
|
||||
!creditListState.custom1Filters.contains(credit.customValue1)) {
|
||||
return false;
|
||||
}
|
||||
if (creditListState.custom2Filters.isNotEmpty &&
|
||||
!creditListState.custom2Filters.contains(credit.customValue2)) {
|
||||
return false;
|
||||
}
|
||||
return credit.matchesFilter(creditListState.filter);
|
||||
}).toList();
|
||||
|
||||
list.sort((creditAId, creditBId) {
|
||||
final creditA = creditMap[creditAId];
|
||||
final creditB = creditMap[creditBId];
|
||||
return creditA.compareTo(
|
||||
creditB, creditListState.sortField, creditListState.sortAscending);
|
||||
});
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
bool hasCreditChanges(
|
||||
InvoiceEntity credit, BuiltMap<String, InvoiceEntity> creditMap) =>
|
||||
credit.isNew ? credit.isChanged : credit != creditMap[credit.id];
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
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/credit_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 'credit_state.g.dart';
|
||||
|
||||
abstract class CreditState implements Built<CreditState, CreditStateBuilder> {
|
||||
factory CreditState() {
|
||||
return _$CreditState._(
|
||||
lastUpdated: 0,
|
||||
map: BuiltMap<String, InvoiceEntity>(),
|
||||
list: BuiltList<String>(),
|
||||
);
|
||||
}
|
||||
CreditState._();
|
||||
|
||||
@nullable
|
||||
int get lastUpdated;
|
||||
|
||||
BuiltMap<String, InvoiceEntity> 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;
|
||||
|
||||
CreditState loadCredits(BuiltList<InvoiceEntity> clients) {
|
||||
final map = Map<String, InvoiceEntity>.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));
|
||||
}
|
||||
|
||||
static Serializer<CreditState> get serializer => _$creditStateSerializer;
|
||||
}
|
||||
|
||||
abstract class CreditUIState extends Object
|
||||
with EntityUIState
|
||||
implements Built<CreditUIState, CreditUIStateBuilder> {
|
||||
factory CreditUIState() {
|
||||
return _$CreditUIState._(
|
||||
listUIState: ListUIState(CreditFields.name),
|
||||
editing: InvoiceEntity(),
|
||||
selectedId: '',
|
||||
);
|
||||
}
|
||||
CreditUIState._();
|
||||
|
||||
@nullable
|
||||
InvoiceEntity get editing;
|
||||
|
||||
@override
|
||||
bool get isCreatingNew => editing.isNew;
|
||||
|
||||
static Serializer<CreditUIState> get serializer => _$creditUIStateSerializer;
|
||||
}
|
||||
|
|
@ -0,0 +1,406 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'credit_state.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// BuiltValueGenerator
|
||||
// **************************************************************************
|
||||
|
||||
Serializer<CreditState> _$creditStateSerializer = new _$CreditStateSerializer();
|
||||
Serializer<CreditUIState> _$creditUIStateSerializer =
|
||||
new _$CreditUIStateSerializer();
|
||||
|
||||
class _$CreditStateSerializer implements StructuredSerializer<CreditState> {
|
||||
@override
|
||||
final Iterable<Type> types = const [CreditState, _$CreditState];
|
||||
@override
|
||||
final String wireName = 'CreditState';
|
||||
|
||||
@override
|
||||
Iterable<Object> serialize(Serializers serializers, CreditState object,
|
||||
{FullType specifiedType = FullType.unspecified}) {
|
||||
final result = <Object>[
|
||||
'map',
|
||||
serializers.serialize(object.map,
|
||||
specifiedType: const FullType(BuiltMap,
|
||||
const [const FullType(String), const FullType(InvoiceEntity)])),
|
||||
'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
|
||||
CreditState deserialize(Serializers serializers, Iterable<Object> serialized,
|
||||
{FullType specifiedType = FullType.unspecified}) {
|
||||
final result = new CreditStateBuilder();
|
||||
|
||||
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(InvoiceEntity)
|
||||
])));
|
||||
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 _$CreditUIStateSerializer implements StructuredSerializer<CreditUIState> {
|
||||
@override
|
||||
final Iterable<Type> types = const [CreditUIState, _$CreditUIState];
|
||||
@override
|
||||
final String wireName = 'CreditUIState';
|
||||
|
||||
@override
|
||||
Iterable<Object> serialize(Serializers serializers, CreditUIState 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(InvoiceEntity)));
|
||||
}
|
||||
if (object.selectedId != null) {
|
||||
result
|
||||
..add('selectedId')
|
||||
..add(serializers.serialize(object.selectedId,
|
||||
specifiedType: const FullType(String)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
CreditUIState deserialize(
|
||||
Serializers serializers, Iterable<Object> serialized,
|
||||
{FullType specifiedType = FullType.unspecified}) {
|
||||
final result = new CreditUIStateBuilder();
|
||||
|
||||
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(InvoiceEntity)) as InvoiceEntity);
|
||||
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 _$CreditState extends CreditState {
|
||||
@override
|
||||
final int lastUpdated;
|
||||
@override
|
||||
final BuiltMap<String, InvoiceEntity> map;
|
||||
@override
|
||||
final BuiltList<String> list;
|
||||
|
||||
factory _$CreditState([void Function(CreditStateBuilder) updates]) =>
|
||||
(new CreditStateBuilder()..update(updates)).build();
|
||||
|
||||
_$CreditState._({this.lastUpdated, this.map, this.list}) : super._() {
|
||||
if (map == null) {
|
||||
throw new BuiltValueNullFieldError('CreditState', 'map');
|
||||
}
|
||||
if (list == null) {
|
||||
throw new BuiltValueNullFieldError('CreditState', 'list');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
CreditState rebuild(void Function(CreditStateBuilder) updates) =>
|
||||
(toBuilder()..update(updates)).build();
|
||||
|
||||
@override
|
||||
CreditStateBuilder toBuilder() => new CreditStateBuilder()..replace(this);
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(other, this)) return true;
|
||||
return other is CreditState &&
|
||||
lastUpdated == other.lastUpdated &&
|
||||
map == other.map &&
|
||||
list == other.list;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return $jf(
|
||||
$jc($jc($jc(0, lastUpdated.hashCode), map.hashCode), list.hashCode));
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return (newBuiltValueToStringHelper('CreditState')
|
||||
..add('lastUpdated', lastUpdated)
|
||||
..add('map', map)
|
||||
..add('list', list))
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
||||
class CreditStateBuilder implements Builder<CreditState, CreditStateBuilder> {
|
||||
_$CreditState _$v;
|
||||
|
||||
int _lastUpdated;
|
||||
int get lastUpdated => _$this._lastUpdated;
|
||||
set lastUpdated(int lastUpdated) => _$this._lastUpdated = lastUpdated;
|
||||
|
||||
MapBuilder<String, InvoiceEntity> _map;
|
||||
MapBuilder<String, InvoiceEntity> get map =>
|
||||
_$this._map ??= new MapBuilder<String, InvoiceEntity>();
|
||||
set map(MapBuilder<String, InvoiceEntity> map) => _$this._map = map;
|
||||
|
||||
ListBuilder<String> _list;
|
||||
ListBuilder<String> get list => _$this._list ??= new ListBuilder<String>();
|
||||
set list(ListBuilder<String> list) => _$this._list = list;
|
||||
|
||||
CreditStateBuilder();
|
||||
|
||||
CreditStateBuilder get _$this {
|
||||
if (_$v != null) {
|
||||
_lastUpdated = _$v.lastUpdated;
|
||||
_map = _$v.map?.toBuilder();
|
||||
_list = _$v.list?.toBuilder();
|
||||
_$v = null;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@override
|
||||
void replace(CreditState other) {
|
||||
if (other == null) {
|
||||
throw new ArgumentError.notNull('other');
|
||||
}
|
||||
_$v = other as _$CreditState;
|
||||
}
|
||||
|
||||
@override
|
||||
void update(void Function(CreditStateBuilder) updates) {
|
||||
if (updates != null) updates(this);
|
||||
}
|
||||
|
||||
@override
|
||||
_$CreditState build() {
|
||||
_$CreditState _$result;
|
||||
try {
|
||||
_$result = _$v ??
|
||||
new _$CreditState._(
|
||||
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(
|
||||
'CreditState', _$failedField, e.toString());
|
||||
}
|
||||
rethrow;
|
||||
}
|
||||
replace(_$result);
|
||||
return _$result;
|
||||
}
|
||||
}
|
||||
|
||||
class _$CreditUIState extends CreditUIState {
|
||||
@override
|
||||
final InvoiceEntity editing;
|
||||
@override
|
||||
final ListUIState listUIState;
|
||||
@override
|
||||
final String selectedId;
|
||||
@override
|
||||
final Completer<SelectableEntity> saveCompleter;
|
||||
@override
|
||||
final Completer<Null> cancelCompleter;
|
||||
|
||||
factory _$CreditUIState([void Function(CreditUIStateBuilder) updates]) =>
|
||||
(new CreditUIStateBuilder()..update(updates)).build();
|
||||
|
||||
_$CreditUIState._(
|
||||
{this.editing,
|
||||
this.listUIState,
|
||||
this.selectedId,
|
||||
this.saveCompleter,
|
||||
this.cancelCompleter})
|
||||
: super._() {
|
||||
if (listUIState == null) {
|
||||
throw new BuiltValueNullFieldError('CreditUIState', 'listUIState');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
CreditUIState rebuild(void Function(CreditUIStateBuilder) updates) =>
|
||||
(toBuilder()..update(updates)).build();
|
||||
|
||||
@override
|
||||
CreditUIStateBuilder toBuilder() => new CreditUIStateBuilder()..replace(this);
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(other, this)) return true;
|
||||
return other is CreditUIState &&
|
||||
editing == other.editing &&
|
||||
listUIState == other.listUIState &&
|
||||
selectedId == other.selectedId &&
|
||||
saveCompleter == other.saveCompleter &&
|
||||
cancelCompleter == other.cancelCompleter;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return $jf($jc(
|
||||
$jc(
|
||||
$jc($jc($jc(0, editing.hashCode), listUIState.hashCode),
|
||||
selectedId.hashCode),
|
||||
saveCompleter.hashCode),
|
||||
cancelCompleter.hashCode));
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return (newBuiltValueToStringHelper('CreditUIState')
|
||||
..add('editing', editing)
|
||||
..add('listUIState', listUIState)
|
||||
..add('selectedId', selectedId)
|
||||
..add('saveCompleter', saveCompleter)
|
||||
..add('cancelCompleter', cancelCompleter))
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
||||
class CreditUIStateBuilder
|
||||
implements Builder<CreditUIState, CreditUIStateBuilder> {
|
||||
_$CreditUIState _$v;
|
||||
|
||||
InvoiceEntityBuilder _editing;
|
||||
InvoiceEntityBuilder get editing =>
|
||||
_$this._editing ??= new InvoiceEntityBuilder();
|
||||
set editing(InvoiceEntityBuilder 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;
|
||||
|
||||
CreditUIStateBuilder();
|
||||
|
||||
CreditUIStateBuilder 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(CreditUIState other) {
|
||||
if (other == null) {
|
||||
throw new ArgumentError.notNull('other');
|
||||
}
|
||||
_$v = other as _$CreditUIState;
|
||||
}
|
||||
|
||||
@override
|
||||
void update(void Function(CreditUIStateBuilder) updates) {
|
||||
if (updates != null) updates(this);
|
||||
}
|
||||
|
||||
@override
|
||||
_$CreditUIState build() {
|
||||
_$CreditUIState _$result;
|
||||
try {
|
||||
_$result = _$v ??
|
||||
new _$CreditUIState._(
|
||||
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(
|
||||
'CreditUIState', _$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
|
||||
|
|
@ -23,6 +23,8 @@ import 'package:invoiceninja_flutter/redux/ui/ui_actions.dart';
|
|||
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/credit/credit_actions.dart';
|
||||
|
||||
import 'package:redux/redux.dart';
|
||||
|
||||
PrefState prefReducer(
|
||||
|
|
@ -395,6 +397,12 @@ Reducer<BuiltList<HistoryRecord>> historyReducer = combineReducers([
|
|||
_addToHistory(historyList,
|
||||
HistoryRecord(id: action.group.id, entityType: EntityType.group))),
|
||||
// STARTER: history - do not remove comment
|
||||
TypedReducer<BuiltList<HistoryRecord>, ViewCredit>((historyList, action) =>
|
||||
_addToHistory(historyList,
|
||||
HistoryRecord(id: action.creditId, entityType: EntityType.credit))),
|
||||
TypedReducer<BuiltList<HistoryRecord>, EditCredit>((historyList, action) =>
|
||||
_addToHistory(historyList,
|
||||
HistoryRecord(id: action.credit.id, entityType: EntityType.credit))),
|
||||
]);
|
||||
|
||||
BuiltList<HistoryRecord> _addToHistory(
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ import 'package:invoiceninja_flutter/redux/quote/quote_reducer.dart';
|
|||
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/credit/credit_reducer.dart';
|
||||
|
||||
import 'package:invoiceninja_flutter/redux/user/user_reducer.dart';
|
||||
import 'package:invoiceninja_flutter/redux/tax_rate/tax_rate_reducer.dart';
|
||||
import 'package:invoiceninja_flutter/redux/company_gateway/company_gateway_reducer.dart';
|
||||
|
|
@ -47,6 +49,7 @@ UIState uiReducer(UIState state, dynamic action) {
|
|||
.replace(dashboardUIReducer(state.dashboardUIState, action))
|
||||
..reportsUIState.replace(reportsUIReducer(state.reportsUIState, action))
|
||||
// STARTER: reducer - do not remove comment
|
||||
..creditUIState.replace(creditUIReducer(state.creditUIState, action))
|
||||
..userUIState.replace(userUIReducer(state.userUIState, action))
|
||||
..taxRateUIState.replace(taxRateUIReducer(state.taxRateUIState, action))
|
||||
..companyGatewayUIState
|
||||
|
|
|
|||
|
|
@ -16,6 +16,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/credit/credit_state.dart';
|
||||
|
||||
import 'package:invoiceninja_flutter/redux/user/user_state.dart';
|
||||
import 'package:invoiceninja_flutter/redux/tax_rate/tax_rate_state.dart';
|
||||
import 'package:invoiceninja_flutter/redux/company_gateway/company_gateway_state.dart';
|
||||
|
|
@ -35,6 +37,8 @@ abstract class UIState implements Built<UIState, UIStateBuilder> {
|
|||
clientUIState: ClientUIState(),
|
||||
invoiceUIState: InvoiceUIState(),
|
||||
// STARTER: constructor - do not remove comment
|
||||
creditUIState: CreditUIState(),
|
||||
|
||||
userUIState: UserUIState(),
|
||||
taxRateUIState: TaxRateUIState(),
|
||||
companyGatewayUIState: CompanyGatewayUIState(),
|
||||
|
|
@ -73,6 +77,8 @@ abstract class UIState implements Built<UIState, UIStateBuilder> {
|
|||
InvoiceUIState get invoiceUIState;
|
||||
|
||||
// STARTER: properties - do not remove comment
|
||||
CreditUIState get creditUIState;
|
||||
|
||||
UserUIState get userUIState;
|
||||
|
||||
TaxRateUIState get taxRateUIState;
|
||||
|
|
|
|||
|
|
@ -42,6 +42,9 @@ class _$UIStateSerializer implements StructuredSerializer<UIState> {
|
|||
'invoiceUIState',
|
||||
serializers.serialize(object.invoiceUIState,
|
||||
specifiedType: const FullType(InvoiceUIState)),
|
||||
'creditUIState',
|
||||
serializers.serialize(object.creditUIState,
|
||||
specifiedType: const FullType(CreditUIState)),
|
||||
'userUIState',
|
||||
serializers.serialize(object.userUIState,
|
||||
specifiedType: const FullType(UserUIState)),
|
||||
|
|
@ -139,6 +142,10 @@ class _$UIStateSerializer implements StructuredSerializer<UIState> {
|
|||
result.invoiceUIState.replace(serializers.deserialize(value,
|
||||
specifiedType: const FullType(InvoiceUIState)) as InvoiceUIState);
|
||||
break;
|
||||
case 'creditUIState':
|
||||
result.creditUIState.replace(serializers.deserialize(value,
|
||||
specifiedType: const FullType(CreditUIState)) as CreditUIState);
|
||||
break;
|
||||
case 'userUIState':
|
||||
result.userUIState.replace(serializers.deserialize(value,
|
||||
specifiedType: const FullType(UserUIState)) as UserUIState);
|
||||
|
|
@ -221,6 +228,8 @@ class _$UIState extends UIState {
|
|||
@override
|
||||
final InvoiceUIState invoiceUIState;
|
||||
@override
|
||||
final CreditUIState creditUIState;
|
||||
@override
|
||||
final UserUIState userUIState;
|
||||
@override
|
||||
final TaxRateUIState taxRateUIState;
|
||||
|
|
@ -260,6 +269,7 @@ class _$UIState extends UIState {
|
|||
this.productUIState,
|
||||
this.clientUIState,
|
||||
this.invoiceUIState,
|
||||
this.creditUIState,
|
||||
this.userUIState,
|
||||
this.taxRateUIState,
|
||||
this.companyGatewayUIState,
|
||||
|
|
@ -298,6 +308,9 @@ class _$UIState extends UIState {
|
|||
if (invoiceUIState == null) {
|
||||
throw new BuiltValueNullFieldError('UIState', 'invoiceUIState');
|
||||
}
|
||||
if (creditUIState == null) {
|
||||
throw new BuiltValueNullFieldError('UIState', 'creditUIState');
|
||||
}
|
||||
if (userUIState == null) {
|
||||
throw new BuiltValueNullFieldError('UIState', 'userUIState');
|
||||
}
|
||||
|
|
@ -359,6 +372,7 @@ class _$UIState extends UIState {
|
|||
productUIState == other.productUIState &&
|
||||
clientUIState == other.clientUIState &&
|
||||
invoiceUIState == other.invoiceUIState &&
|
||||
creditUIState == other.creditUIState &&
|
||||
userUIState == other.userUIState &&
|
||||
taxRateUIState == other.taxRateUIState &&
|
||||
companyGatewayUIState == other.companyGatewayUIState &&
|
||||
|
|
@ -394,13 +408,13 @@ class _$UIState extends UIState {
|
|||
$jc(
|
||||
$jc(
|
||||
$jc(
|
||||
$jc($jc($jc($jc(0, selectedCompanyIndex.hashCode), currentRoute.hashCode), previousRoute.hashCode),
|
||||
filter.hashCode),
|
||||
filterClearedAt.hashCode),
|
||||
dashboardUIState.hashCode),
|
||||
productUIState.hashCode),
|
||||
clientUIState.hashCode),
|
||||
invoiceUIState.hashCode),
|
||||
$jc($jc($jc($jc($jc(0, selectedCompanyIndex.hashCode), currentRoute.hashCode), previousRoute.hashCode), filter.hashCode),
|
||||
filterClearedAt.hashCode),
|
||||
dashboardUIState.hashCode),
|
||||
productUIState.hashCode),
|
||||
clientUIState.hashCode),
|
||||
invoiceUIState.hashCode),
|
||||
creditUIState.hashCode),
|
||||
userUIState.hashCode),
|
||||
taxRateUIState.hashCode),
|
||||
companyGatewayUIState.hashCode),
|
||||
|
|
@ -428,6 +442,7 @@ class _$UIState extends UIState {
|
|||
..add('productUIState', productUIState)
|
||||
..add('clientUIState', clientUIState)
|
||||
..add('invoiceUIState', invoiceUIState)
|
||||
..add('creditUIState', creditUIState)
|
||||
..add('userUIState', userUIState)
|
||||
..add('taxRateUIState', taxRateUIState)
|
||||
..add('companyGatewayUIState', companyGatewayUIState)
|
||||
|
|
@ -495,6 +510,12 @@ class UIStateBuilder implements Builder<UIState, UIStateBuilder> {
|
|||
set invoiceUIState(InvoiceUIStateBuilder invoiceUIState) =>
|
||||
_$this._invoiceUIState = invoiceUIState;
|
||||
|
||||
CreditUIStateBuilder _creditUIState;
|
||||
CreditUIStateBuilder get creditUIState =>
|
||||
_$this._creditUIState ??= new CreditUIStateBuilder();
|
||||
set creditUIState(CreditUIStateBuilder creditUIState) =>
|
||||
_$this._creditUIState = creditUIState;
|
||||
|
||||
UserUIStateBuilder _userUIState;
|
||||
UserUIStateBuilder get userUIState =>
|
||||
_$this._userUIState ??= new UserUIStateBuilder();
|
||||
|
|
@ -587,6 +608,7 @@ class UIStateBuilder implements Builder<UIState, UIStateBuilder> {
|
|||
_productUIState = _$v.productUIState?.toBuilder();
|
||||
_clientUIState = _$v.clientUIState?.toBuilder();
|
||||
_invoiceUIState = _$v.invoiceUIState?.toBuilder();
|
||||
_creditUIState = _$v.creditUIState?.toBuilder();
|
||||
_userUIState = _$v.userUIState?.toBuilder();
|
||||
_taxRateUIState = _$v.taxRateUIState?.toBuilder();
|
||||
_companyGatewayUIState = _$v.companyGatewayUIState?.toBuilder();
|
||||
|
|
@ -633,6 +655,7 @@ class UIStateBuilder implements Builder<UIState, UIStateBuilder> {
|
|||
productUIState: productUIState.build(),
|
||||
clientUIState: clientUIState.build(),
|
||||
invoiceUIState: invoiceUIState.build(),
|
||||
creditUIState: creditUIState.build(),
|
||||
userUIState: userUIState.build(),
|
||||
taxRateUIState: taxRateUIState.build(),
|
||||
companyGatewayUIState: companyGatewayUIState.build(),
|
||||
|
|
@ -657,6 +680,8 @@ class UIStateBuilder implements Builder<UIState, UIStateBuilder> {
|
|||
clientUIState.build();
|
||||
_$failedField = 'invoiceUIState';
|
||||
invoiceUIState.build();
|
||||
_$failedField = 'creditUIState';
|
||||
creditUIState.build();
|
||||
_$failedField = 'userUIState';
|
||||
userUIState.build();
|
||||
_$failedField = 'taxRateUIState';
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import 'package:invoiceninja_flutter/utils/platforms.dart';
|
|||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
// STARTER: import - do not remove comment
|
||||
import 'package:invoiceninja_flutter/redux/credit/credit_actions.dart';
|
||||
|
||||
class MenuDrawer extends StatelessWidget {
|
||||
const MenuDrawer({
|
||||
|
|
@ -253,6 +254,19 @@ class MenuDrawer extends StatelessWidget {
|
|||
title: localization.expenses,
|
||||
),
|
||||
// STARTER: menu - do not remove comment
|
||||
DrawerTile(
|
||||
company: company,
|
||||
entityType: EntityType.credit,
|
||||
icon: getEntityIcon(EntityType.credit),
|
||||
title: localization.credits,
|
||||
onTap: () => store.dispatch(ViewcreditList(context)),
|
||||
onCreateTap: () {
|
||||
navigator.pop();
|
||||
store.dispatch(EditCredit(
|
||||
credit: InvoiceEntity(), context: context));
|
||||
},
|
||||
),
|
||||
|
||||
DrawerTile(
|
||||
company: company,
|
||||
icon: getEntityIcon(EntityType.reports),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,134 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
|
||||
import 'package:invoiceninja_flutter/data/models/models.dart';
|
||||
import 'package:invoiceninja_flutter/ui/app/entities/entity_actions_dialog.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/help_text.dart';
|
||||
import 'package:invoiceninja_flutter/ui/app/snackbar_row.dart';
|
||||
import 'package:invoiceninja_flutter/ui/credit/credit_list_item.dart';
|
||||
import 'package:invoiceninja_flutter/ui/credit/credit_list_vm.dart';
|
||||
import 'package:invoiceninja_flutter/ui/app/presenters/entity_presenter.dart';
|
||||
import 'package:invoiceninja_flutter/ui/app/tables/entity_datatable.dart';
|
||||
import 'package:invoiceninja_flutter/utils/icons.dart';
|
||||
import 'package:invoiceninja_flutter/utils/localization.dart';
|
||||
import 'package:invoiceninja_flutter/utils/platforms.dart';
|
||||
|
||||
class CreditList extends StatefulWidget {
|
||||
const CreditList({
|
||||
Key key,
|
||||
@required this.viewModel,
|
||||
}) : super(key: key);
|
||||
|
||||
final CreditListVM viewModel;
|
||||
|
||||
@override
|
||||
_CreditListState createState() => _CreditListState();
|
||||
}
|
||||
|
||||
class _CreditListState extends State<CreditList> {
|
||||
EntityDataTableSource dataTableSource;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
final viewModel = widget.viewModel;
|
||||
|
||||
dataTableSource = EntityDataTableSource(
|
||||
context: context,
|
||||
entityType: EntityType.credit,
|
||||
editingId: viewModel.state.creditUIState.editing.id,
|
||||
tableColumns: viewModel.tableColumns,
|
||||
entityList: viewModel.creditList,
|
||||
entityMap: viewModel.creditMap,
|
||||
entityPresenter: CreditPresenter(),
|
||||
onTap: (BaseEntity credit) => viewModel.onCreditTap(context, credit));
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(CreditList oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
|
||||
final viewModel = widget.viewModel;
|
||||
dataTableSource.editingId = viewModel.state.creditUIState.editing.id;
|
||||
dataTableSource.entityList = viewModel.creditList;
|
||||
dataTableSource.entityMap = viewModel.creditMap;
|
||||
|
||||
// ignore: invalid_use_of_visible_for_testing_member, invalid_use_of_protected_member
|
||||
dataTableSource.notifyListeners();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
/*
|
||||
final localization = AppLocalization.of(context);
|
||||
final listState = viewModel.listState;
|
||||
final filteredClientId = listState.filterEntityId;
|
||||
final filteredClient =
|
||||
filteredClientId != null ? viewModel.clientMap[filteredClientId] : null;
|
||||
*/
|
||||
final store = StoreProvider.of<AppState>(context);
|
||||
final listUIState = store.state.uiState.creditUIState.listUIState;
|
||||
final isInMultiselect = listUIState.isInMultiselect();
|
||||
final creditList = viewModel.creditList;
|
||||
|
||||
if (isNotMobile(context) &&
|
||||
creditList.isNotEmpty &&
|
||||
!state.uiState.isEditing &&
|
||||
!creditList.contains(state.creditUIState.selectedId)) {
|
||||
viewEntityById(
|
||||
context: context,
|
||||
entityType: EntityType.credit,
|
||||
entityId: creditList.first);
|
||||
}
|
||||
|
||||
return Column(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: !viewModel.isLoaded
|
||||
? LoadingIndicator()
|
||||
: RefreshIndicator(
|
||||
onRefresh: () => viewModel.onRefreshed(context),
|
||||
child: viewModel.creditList.isEmpty
|
||||
? HelpText(AppLocalization.of(context).noRecordsFound)
|
||||
: ListView.separated(
|
||||
shrinkWrap: true,
|
||||
separatorBuilder: (context, index) => ListDivider(),
|
||||
itemCount: viewModel.creditList.length,
|
||||
itemBuilder: (BuildContext context, index) {
|
||||
final creditId = viewModel.creditList[index];
|
||||
final credit = viewModel.creditMap[creditId];
|
||||
final userCompany = viewModel.userCompany;
|
||||
|
||||
void showDialog() => showEntityActionsDialog(
|
||||
userCompany: userCompany,
|
||||
entity: credit,
|
||||
context: context,
|
||||
onEntityAction: viewModel.onEntityAction);
|
||||
|
||||
return CreditListItem(
|
||||
user: viewModel.userCompany.user,
|
||||
filter: viewModel.filter,
|
||||
credit: credit,
|
||||
onTap: () =>
|
||||
viewModel.onCreditTap(context, credit),
|
||||
onEntityAction: (EntityAction action) {
|
||||
if (action == EntityAction.more) {
|
||||
showDialog();
|
||||
} else {
|
||||
viewModel.onEntityAction(
|
||||
context, credit, action);
|
||||
}
|
||||
},
|
||||
onLongPress: () => showDialog(),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
import 'package:flutter_redux/flutter_redux.dart';
|
||||
import 'package:invoiceninja_flutter/data/models/credit_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 CreditListItem extends StatelessWidget {
|
||||
const CreditListItem({
|
||||
@required this.user,
|
||||
@required this.onEntityAction,
|
||||
@required this.onTap,
|
||||
@required this.onLongPress,
|
||||
@required this.credit,
|
||||
@required this.filter,
|
||||
this.onCheckboxChanged,
|
||||
this.isChecked = false,
|
||||
});
|
||||
|
||||
final UserEntity user;
|
||||
final Function(EntityAction) onEntityAction;
|
||||
final GestureTapCallback onTap;
|
||||
final GestureTapCallback onLongPress;
|
||||
final InvoiceEntity credit;
|
||||
final String filter;
|
||||
final Function(bool) onCheckboxChanged;
|
||||
final bool isChecked;
|
||||
|
||||
static final creditItemKey = (int id) => Key('__credit_item_${id}__');
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final store = StoreProvider.of<AppState>(context);
|
||||
final state = store.state;
|
||||
final uiState = state.uiState;
|
||||
final creditUIState = uiState.creditUIState;
|
||||
final listUIState = creditUIState.listUIState;
|
||||
final isInMultiselect = listUIState.isInMultiselect();
|
||||
final showCheckbox = onCheckboxChanged != null || isInMultiselect;
|
||||
|
||||
final filterMatch = filter != null && filter.isNotEmpty
|
||||
? credit.matchesFilterValue(filter)
|
||||
: null;
|
||||
final subtitle = filterMatch;
|
||||
|
||||
return DismissibleEntity(
|
||||
userCompany: state.userCompany,
|
||||
entity: credit,
|
||||
isSelected: credit.id ==
|
||||
(uiState.isEditing
|
||||
? creditUIState.editing.id
|
||||
: creditUIState.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(
|
||||
credit.name,
|
||||
style: Theme.of(context).textTheme.headline6,
|
||||
),
|
||||
),
|
||||
Text(formatNumber(credit.listDisplayAmount, context),
|
||||
style: Theme.of(context).textTheme.headline6),
|
||||
],
|
||||
),
|
||||
),
|
||||
subtitle: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
subtitle != null && subtitle.isNotEmpty
|
||||
? Text(
|
||||
subtitle,
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
)
|
||||
: Container(),
|
||||
EntityStateLabel(credit),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
import 'dart:async';
|
||||
import 'package:invoiceninja_flutter/data/models/credit_model.dart';
|
||||
import 'package:redux/redux.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/client/client_actions.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/credit/credit_selectors.dart';
|
||||
import 'package:invoiceninja_flutter/data/models/models.dart';
|
||||
import 'package:invoiceninja_flutter/ui/credit/credit_list.dart';
|
||||
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
|
||||
import 'package:invoiceninja_flutter/redux/credit/credit_actions.dart';
|
||||
|
||||
class CreditListBuilder extends StatelessWidget {
|
||||
const CreditListBuilder({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return StoreConnector<AppState, CreditListVM>(
|
||||
converter: CreditListVM.fromStore,
|
||||
builder: (context, viewModel) {
|
||||
return CreditList(
|
||||
viewModel: viewModel,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class CreditListVM {
|
||||
CreditListVM({
|
||||
@required this.userCompany,
|
||||
@required this.creditList,
|
||||
@required this.creditMap,
|
||||
@required this.filter,
|
||||
@required this.isLoading,
|
||||
@required this.isLoaded,
|
||||
@required this.onCreditTap,
|
||||
@required this.listState,
|
||||
@required this.onRefreshed,
|
||||
@required this.onEntityAction,
|
||||
@required this.tableColumns,
|
||||
@required this.onClearEntityFilterPressed,
|
||||
@required this.onViewEntityFilterPressed,
|
||||
});
|
||||
|
||||
static CreditListVM 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(LoadCredits(completer: completer, force: true));
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
final state = store.state;
|
||||
|
||||
return CreditListVM(
|
||||
userCompany: state.userCompany,
|
||||
listState: state.creditListState,
|
||||
creditList: memoizedFilteredCreditList(
|
||||
state.creditState.map, state.creditState.list, state.creditListState),
|
||||
creditMap: state.creditState.map,
|
||||
isLoading: state.isLoading,
|
||||
isLoaded: state.creditState.isLoaded,
|
||||
filter: state.creditUIState.listUIState.filter,
|
||||
onClearEntityFilterPressed: () => store.dispatch(FilterCreditsByEntity()),
|
||||
onViewEntityFilterPressed: (BuildContext context) => viewEntityById(
|
||||
context: context,
|
||||
entityId: state.creditListState.filterEntityId,
|
||||
entityType: state.creditListState.filterEntityType),
|
||||
onCreditTap: (context, credit) {
|
||||
if (store.state.creditListState.isInMultiselect()) {
|
||||
handleCreditAction(context, [credit], EntityAction.toggleMultiselect);
|
||||
} else {
|
||||
viewEntity(context: context, entity: credit);
|
||||
}
|
||||
},
|
||||
onEntityAction: (BuildContext context, List<BaseEntity> credits,
|
||||
EntityAction action) =>
|
||||
handleCreditAction(context, credits, action),
|
||||
onRefreshed: (context) => _handleRefresh(context),
|
||||
);
|
||||
}
|
||||
|
||||
final UserCompanyEntity userCompany;
|
||||
final List<String> creditList;
|
||||
final BuiltMap<String, InvoiceEntity> creditMap;
|
||||
final ListUIState listState;
|
||||
final String filter;
|
||||
final bool isLoading;
|
||||
final bool isLoaded;
|
||||
final Function(BuildContext, InvoiceEntity) onCreditTap;
|
||||
final Function(BuildContext) onRefreshed;
|
||||
final Function(BuildContext, List<BaseEntity>, EntityAction) onEntityAction;
|
||||
final Function onClearEntityFilterPressed;
|
||||
final Function(BuildContext) onViewEntityFilterPressed;
|
||||
final List<String> tableColumns;
|
||||
}
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_redux/flutter_redux.dart';
|
||||
import 'package:invoiceninja_flutter/ui/app/app_scaffold.dart';
|
||||
import 'package:invoiceninja_flutter/redux/dashboard/dashboard_actions.dart';
|
||||
import 'package:invoiceninja_flutter/data/models/credit_model.dart';
|
||||
import 'package:invoiceninja_flutter/ui/app/list_filter.dart';
|
||||
import 'package:invoiceninja_flutter/ui/app/list_filter_button.dart';
|
||||
import 'package:invoiceninja_flutter/utils/localization.dart';
|
||||
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
|
||||
import 'package:invoiceninja_flutter/data/models/models.dart';
|
||||
import 'package:invoiceninja_flutter/ui/credit/credit_list_vm.dart';
|
||||
import 'package:invoiceninja_flutter/redux/credit/credit_actions.dart';
|
||||
import 'package:invoiceninja_flutter/ui/app/app_drawer_vm.dart';
|
||||
import 'package:invoiceninja_flutter/ui/app/app_bottom_bar.dart';
|
||||
import 'package:invoiceninja_flutter/ui/app/entities/entity_actions_dialog.dart';
|
||||
|
||||
class CreditScreen extends StatelessWidget {
|
||||
const CreditScreen({
|
||||
Key key,
|
||||
@required this.viewModel,
|
||||
}) : super(key: key);
|
||||
|
||||
static const String route = '/credit';
|
||||
|
||||
final CreditScreenVM viewModel;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final store = StoreProvider.of<AppState>(context);
|
||||
final state = store.state;
|
||||
final company = state.selectedCompany;
|
||||
final localization = AppLocalization.of(context);
|
||||
final listUIState = state.uiState.creditUIState.listUIState;
|
||||
final isInMultiselect = listUIState.isInMultiselect();
|
||||
|
||||
return AppScaffold(
|
||||
isChecked: isInMultiselect &&
|
||||
listUIState.selectedIds.length == viewModel.creditList.length,
|
||||
showCheckbox: isInMultiselect,
|
||||
onCheckboxChanged: (value) {
|
||||
final credits = viewModel.creditList
|
||||
.map<InvoiceEntity>((creditId) => viewModel.creditMap[creditId])
|
||||
.where((credit) => value != listUIState.isSelected(credit))
|
||||
.toList();
|
||||
|
||||
viewModel.onEntityAction(
|
||||
context, credits, EntityAction.toggleMultiselect);
|
||||
},
|
||||
appBarTitle: ListFilter(
|
||||
title: localization.credits
|
||||
key: ValueKey(state.creditListState.filterClearedAt),
|
||||
entityType: EntityType.credit,
|
||||
onFilterChanged: (value) {
|
||||
store.dispatch(FilterCredits(value));
|
||||
},
|
||||
),
|
||||
appBarActions: [
|
||||
if (!viewModel.isInMultiselect)
|
||||
ListFilterButton(
|
||||
entityType: EntityType.credit,
|
||||
onFilterPressed: (String value) {
|
||||
store.dispatch(FilterCredits(value));
|
||||
},
|
||||
),
|
||||
if (viewModel.isInMultiselect)
|
||||
SaveCancelButtons(
|
||||
saveLabel: localization.done,
|
||||
onSavePressed: listUIState.selectedIds.isEmpty
|
||||
? null
|
||||
: (context) async {
|
||||
final credits = listUIState.selectedIds
|
||||
.map<InvoiceEntity>(
|
||||
(creditId) => viewModel.creditMap[creditId])
|
||||
.toList();
|
||||
|
||||
await showEntityActionsDialog(
|
||||
entities: credits, context: context, multiselect: true,
|
||||
completer: Completer<Null>()
|
||||
..future.then((_) =>
|
||||
store.dispatch(ClearCreditMultiselect())),
|
||||
);
|
||||
},
|
||||
onCancelPressed: (context) =>
|
||||
store.dispatch(ClearCreditMultiselect()),
|
||||
),
|
||||
],
|
||||
body: CreditListBuilder(),
|
||||
bottomNavigationBar: AppBottomBar(
|
||||
entityType: EntityType.credit,
|
||||
onSelectedSortField: (value) => store.dispatch(SortCredits(value)),
|
||||
customValues1: company.getCustomFieldValues(CustomFieldType.credit1,
|
||||
excludeBlank: true),
|
||||
customValues2: company.getCustomFieldValues(CustomFieldType.credit2,
|
||||
excludeBlank: true),
|
||||
onSelectedCustom1: (value) =>
|
||||
store.dispatch(FilterCreditsByCustom1(value)),
|
||||
onSelectedCustom2: (value) =>
|
||||
store.dispatch(FilterCreditsByCustom2(value)),
|
||||
sortFields: [
|
||||
CreditFields.updatedAt,
|
||||
],
|
||||
onSelectedState: (EntityState state, value) {
|
||||
store.dispatch(FilterCreditsByState(state));
|
||||
},
|
||||
onCheckboxPressed: () {
|
||||
if (store.state.creditListState.isInMultiselect()) {
|
||||
store.dispatch(ClearCreditMultiselect());
|
||||
} else {
|
||||
store.dispatch(StartCreditMultiselect());
|
||||
}
|
||||
},
|
||||
),
|
||||
floatingActionButton: user.canCreate(EntityType.credit)
|
||||
? FloatingActionButton(
|
||||
heroTag: 'credit_fab',
|
||||
backgroundColor: Theme.of(context).primaryColorDark,
|
||||
onPressed: () {
|
||||
store.dispatch(
|
||||
EditCredit(credit: InvoiceEntity(), context: context));
|
||||
},
|
||||
child: Icon(
|
||||
Icons.add,
|
||||
color: Colors.white,
|
||||
),
|
||||
tooltip: localization.newCredit,
|
||||
)
|
||||
: null,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:invoiceninja_flutter/ui/settings/edit_scaffold.dart';
|
||||
import 'package:invoiceninja_flutter/ui/app/form_card.dart';
|
||||
import 'package:invoiceninja_flutter/ui/credit/edit/credit_edit_vm.dart';
|
||||
import 'package:invoiceninja_flutter/ui/app/buttons/action_icon_button.dart';
|
||||
import 'package:invoiceninja_flutter/utils/localization.dart';
|
||||
import 'package:invoiceninja_flutter/utils/platforms.dart';
|
||||
import 'package:invoiceninja_flutter/utils/completers.dart';
|
||||
|
||||
class CreditEdit extends StatefulWidget {
|
||||
const CreditEdit({
|
||||
Key key,
|
||||
@required this.viewModel,
|
||||
}) : super(key: key);
|
||||
|
||||
final CreditEditVM viewModel;
|
||||
|
||||
@override
|
||||
_CreditEditState createState() => _CreditEditState();
|
||||
}
|
||||
|
||||
class _CreditEditState extends State<CreditEdit> {
|
||||
static final GlobalKey<FormState> _formKey =
|
||||
GlobalKey<FormState>(debugLabel: '_creditEdit');
|
||||
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 credit = widget.viewModel.credit;
|
||||
// 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 credit = widget.viewModel.credit.rebuild((b) => b
|
||||
// STARTER: set value - do not remove comment
|
||||
);
|
||||
if (credit != widget.viewModel.credit) {
|
||||
widget.viewModel.onChanged(credit);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final viewModel = widget.viewModel;
|
||||
final localization = AppLocalization.of(context);
|
||||
final credit = viewModel.credit;
|
||||
|
||||
return EditScaffold(
|
||||
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
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
})),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
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/ui/ui_actions.dart';
|
||||
import 'package:invoiceninja_flutter/ui/credit/credit_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/credit/view/credit_view_vm.dart';
|
||||
import 'package:invoiceninja_flutter/redux/credit/credit_actions.dart';
|
||||
import 'package:invoiceninja_flutter/data/models/credit_model.dart';
|
||||
import 'package:invoiceninja_flutter/ui/credit/edit/credit_edit.dart';
|
||||
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
|
||||
|
||||
class CreditEditScreen extends StatelessWidget {
|
||||
const CreditEditScreen({Key key}) : super(key: key);
|
||||
static const String route = '/credit/edit';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return StoreConnector<AppState, CreditEditVM>(
|
||||
converter: (Store<AppState> store) {
|
||||
return CreditEditVM.fromStore(store);
|
||||
},
|
||||
builder: (context, viewModel) {
|
||||
return CreditEdit(
|
||||
viewModel: viewModel,
|
||||
key: ValueKey(viewModel.credit.id),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class CreditEditVM {
|
||||
CreditEditVM({
|
||||
@required this.state,
|
||||
@required this.credit,
|
||||
@required this.company,
|
||||
@required this.onChanged,
|
||||
@required this.isSaving,
|
||||
@required this.origCredit,
|
||||
@required this.onSavePressed,
|
||||
@required this.onCancelPressed,
|
||||
@required this.isLoading,
|
||||
});
|
||||
|
||||
factory CreditEditVM.fromStore(Store<AppState> store) {
|
||||
final state = store.state;
|
||||
final credit = state.creditUIState.editing;
|
||||
|
||||
return CreditEditVM(
|
||||
state: state,
|
||||
isLoading: state.isLoading,
|
||||
isSaving: state.isSaving,
|
||||
origCredit: state.creditState.map[credit.id],
|
||||
credit: credit,
|
||||
company: state.selectedCompany,
|
||||
onChanged: (InvoiceEntity credit) {
|
||||
store.dispatch(UpdateCredit(credit));
|
||||
},
|
||||
onCancelPressed: (BuildContext context) {
|
||||
store.dispatch(
|
||||
EditCredit(credit: InvoiceEntity(), context: context, force: true));
|
||||
store.dispatch(UpdateCurrentRoute(state.uiState.previousRoute));
|
||||
},
|
||||
onSavePressed: (BuildContext context) {
|
||||
final Completer<InvoiceEntity> completer = new Completer<InvoiceEntity>();
|
||||
store.dispatch(SaveCreditRequest(completer: completer, credit: credit));
|
||||
return completer.future.then((savedCredit) {
|
||||
if (isMobile(context)) {
|
||||
store.dispatch(UpdateCurrentRoute(CreditViewScreen.route));
|
||||
if (credit.isNew) {
|
||||
Navigator.of(context)
|
||||
.pushReplacementNamed(CreditViewScreen.route);
|
||||
} else {
|
||||
Navigator.of(context).pop(savedCredit);
|
||||
}
|
||||
} else {
|
||||
store.dispatch(ViewCredit(
|
||||
context: context, creditId: savedCredit.id, force: true));
|
||||
}
|
||||
}).catchError((Object error) {
|
||||
showDialog<ErrorDialog>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return ErrorDialog(error);
|
||||
});
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
final InvoiceEntity credit;
|
||||
final CompanyEntity company;
|
||||
final Function(InvoiceEntity) onChanged;
|
||||
final Function(BuildContext) onSavePressed;
|
||||
final Function(BuildContext) onCancelPressed;
|
||||
final bool isLoading;
|
||||
final bool isSaving;
|
||||
final InvoiceEntity origCredit;
|
||||
final AppState state;
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:invoiceninja_flutter/ui/app/buttons/edit_icon_button.dart';
|
||||
import 'package:invoiceninja_flutter/ui/app/actions_menu_button.dart';
|
||||
import 'package:invoiceninja_flutter/ui/credit/view/credit_view_vm.dart';
|
||||
import 'package:invoiceninja_flutter/ui/app/form_card.dart';
|
||||
import 'package:invoiceninja_flutter/ui/app/entities/entity_state_title.dart';
|
||||
|
||||
class CreditView extends StatefulWidget {
|
||||
const CreditView({
|
||||
Key key,
|
||||
@required this.viewModel,
|
||||
}) : super(key: key);
|
||||
|
||||
final CreditViewVM viewModel;
|
||||
|
||||
@override
|
||||
_CreditViewState createState() => new _CreditViewState();
|
||||
}
|
||||
|
||||
class _CreditViewState extends State<CreditView> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final viewModel = widget.viewModel;
|
||||
final userCompany = viewModel.state.userCompany;
|
||||
final credit = viewModel.credit;
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: EntityStateTitle(entity: credit),
|
||||
actions: [
|
||||
userCompany.canEditEntity(credit)
|
||||
? EditIconButton(
|
||||
isVisible: !credit.isDeleted,
|
||||
onPressed: () => viewModel.onEditPressed(context),
|
||||
)
|
||||
: Container(),
|
||||
ActionMenuButton(
|
||||
entityActions: credit.getActions(userCompany: userCompany),
|
||||
isSaving: viewModel.isSaving,
|
||||
entity: credit,
|
||||
onSelected: viewModel.onEntityAction,
|
||||
)
|
||||
],
|
||||
),
|
||||
body: FormCard(children: [
|
||||
// STARTER: widgets - do not remove comment
|
||||
]),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
import 'dart:async';
|
||||
import 'package:invoiceninja_flutter/ui/app/snackbar_row.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:invoiceninja_flutter/redux/ui/ui_actions.dart';
|
||||
import 'package:invoiceninja_flutter/utils/completers.dart';
|
||||
import 'package:invoiceninja_flutter/ui/credit/credit_screen.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/credit/credit_actions.dart';
|
||||
import 'package:invoiceninja_flutter/data/models/credit_model.dart';
|
||||
import 'package:invoiceninja_flutter/data/models/models.dart';
|
||||
import 'package:invoiceninja_flutter/ui/credit/view/credit_view.dart';
|
||||
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
|
||||
|
||||
class CreditViewScreen extends StatelessWidget {
|
||||
const CreditViewScreen({Key key}) : super(key: key);
|
||||
static const String route = '/credit/view';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return StoreConnector<AppState, CreditViewVM>(
|
||||
converter: (Store<AppState> store) {
|
||||
return CreditViewVM.fromStore(store);
|
||||
},
|
||||
builder: (context, vm) {
|
||||
return CreditView(
|
||||
viewModel: vm,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class CreditViewVM {
|
||||
CreditViewVM({
|
||||
@required this.state,
|
||||
@required this.credit,
|
||||
@required this.company,
|
||||
@required this.onEntityAction,
|
||||
@required this.onRefreshed,
|
||||
@required this.isSaving,
|
||||
@required this.isLoading,
|
||||
@required this.isDirty,
|
||||
});
|
||||
|
||||
factory CreditViewVM.fromStore(Store<AppState> store) {
|
||||
final state = store.state;
|
||||
final credit = state.creditState.map[state.creditUIState.selectedId] ??
|
||||
InvoiceEntity(id: state.creditUIState.selectedId);
|
||||
|
||||
Future<Null> _handleRefresh(BuildContext context) {
|
||||
final completer = snackBarCompleter<Null>(
|
||||
context, AppLocalization.of(context).refreshComplete);
|
||||
store.dispatch(LoadCredit(completer: completer, creditId: credit.id));
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
return CreditViewVM(
|
||||
state: state,
|
||||
company: state.selectedCompany,
|
||||
isSaving: state.isSaving,
|
||||
isLoading: state.isLoading,
|
||||
isDirty: credit.isNew,
|
||||
credit: credit,
|
||||
onRefreshed: (context) => _handleRefresh(context),
|
||||
onEntityAction: (BuildContext context, EntityAction action) =>
|
||||
handleCreditAction(context, credit, action),
|
||||
);
|
||||
}
|
||||
|
||||
final AppState state;
|
||||
final InvoiceEntity credit;
|
||||
final CompanyEntity company;
|
||||
final Function(BuildContext, EntityAction) onEntityAction;
|
||||
final Function(BuildContext) onRefreshed;
|
||||
final bool isSaving;
|
||||
final bool isLoading;
|
||||
final bool isDirty;
|
||||
}
|
||||
|
|
@ -24,7 +24,7 @@ enum CreditReportFields {
|
|||
var memoizedCreditReport = memo6((
|
||||
UserCompanyEntity userCompany,
|
||||
ReportsUIState reportsUIState,
|
||||
BuiltMap<String, CreditEntity> creditMap,
|
||||
BuiltMap<String, InvoiceEntity> creditMap,
|
||||
BuiltMap<String, ClientEntity> clientMap,
|
||||
BuiltMap<String, UserEntity> userMap,
|
||||
StaticState staticState,
|
||||
|
|
@ -35,7 +35,7 @@ var memoizedCreditReport = memo6((
|
|||
ReportResult creditReport(
|
||||
UserCompanyEntity userCompany,
|
||||
ReportsUIState reportsUIState,
|
||||
BuiltMap<String, CreditEntity> creditMap,
|
||||
BuiltMap<String, InvoiceEntity> creditMap,
|
||||
BuiltMap<String, ClientEntity> clientMap,
|
||||
BuiltMap<String, UserEntity> userMap,
|
||||
StaticState staticState,
|
||||
|
|
|
|||
|
|
@ -15,6 +15,17 @@ mixin LocalizationsProvider on LocaleCodeAware {
|
|||
static final Map<String, Map<String, String>> _localizedValues = {
|
||||
'en': {
|
||||
// STARTER: lang key - do not remove comment
|
||||
'credit': 'Credit',
|
||||
'credits': 'Credits',
|
||||
'new_credit': 'New Credit',
|
||||
'edit_credit': 'Edit Credit',
|
||||
'created_credit': 'Successfully created credit',
|
||||
'updated_credit': 'Successfully updated credit',
|
||||
'archived_credit': 'Successfully archived credit',
|
||||
'deleted_credit': 'Successfully deleted credit',
|
||||
'removed_credit': 'Successfully removed credit',
|
||||
'restored_credit': 'Successfully restored credit',
|
||||
|
||||
'current_version': 'Current Version',
|
||||
'latest_version': 'Latest Version',
|
||||
'update_now': 'Update Now',
|
||||
|
|
@ -32754,6 +32765,15 @@ mixin LocalizationsProvider on LocaleCodeAware {
|
|||
String get appUpdated => _localizedValues[localeCode]['app_updated'];
|
||||
|
||||
// STARTER: lang field - do not remove comment
|
||||
String get credit => _localizedValues[localeCode][' credit'];
|
||||
String get credits => _localizedValues[localeCode][' credits'];
|
||||
String get newCredit => _localizedValues[localeCode]['new_ credit'];
|
||||
String get createdCredit => _localizedValues[localeCode]['created_ credit'];
|
||||
String get updatedCredit => _localizedValues[localeCode]['updated_ credit'];
|
||||
String get archivedCredit => _localizedValues[localeCode]['archived_ credit'];
|
||||
String get deletedCredit => _localizedValues[localeCode]['deleted_ credit'];
|
||||
String get restoredCredit => _localizedValues[localeCode]['restored_ credit'];
|
||||
String get editCredit => _localizedValues[localeCode]['edit_ credit'];
|
||||
|
||||
String lookup(String key) {
|
||||
final lookupKey = toSnakeCase(key);
|
||||
|
|
|
|||
|
|
@ -44,6 +44,22 @@ class StubRepository {
|
|||
return stubResponse.data;
|
||||
}
|
||||
|
||||
Future<List<StubEntity>> bulkAction(
|
||||
Credentials credentials, List<String> ids, EntityAction action) async {
|
||||
var url = credentials.url + '/stubs/bulk?';
|
||||
if (action != null) {
|
||||
url += '&action=' + action.toString();
|
||||
}
|
||||
final dynamic response = await webClient.post(url, credentials.token,
|
||||
data: json.encode({'ids': ids}));
|
||||
|
||||
final StubListResponse stubResponse =
|
||||
serializers.deserializeWith(StubListResponse.serializer, response);
|
||||
|
||||
return stubResponse.data.toList();
|
||||
}
|
||||
|
||||
|
||||
Future<StubEntity> saveData(
|
||||
Credentials credentials, StubEntity stub,
|
||||
[EntityAction action]) async {
|
||||
|
|
|
|||
|
|
@ -149,66 +149,64 @@ class SaveStubFailure implements StopSaving {
|
|||
final Object error;
|
||||
}
|
||||
|
||||
class ArchiveStubRequest implements StartSaving {
|
||||
ArchiveStubRequest(this.completer, this.stubId);
|
||||
class ArchiveStubsRequest implements StartSaving {
|
||||
ArchiveStubsRequest(this.completer, this.stubIds);
|
||||
|
||||
final Completer completer;
|
||||
final String stubId;
|
||||
final List<String> stubIds;
|
||||
}
|
||||
|
||||
class ArchiveStubSuccess implements StopSaving, PersistData {
|
||||
ArchiveStubSuccess(this.stub);
|
||||
class ArchiveStubsSuccess implements StopSaving, PersistData {
|
||||
ArchiveStubsSuccess(this.stubs);
|
||||
|
||||
final StubEntity stub;
|
||||
final List<StubEntity> stubs;
|
||||
}
|
||||
|
||||
class ArchiveStubFailure implements StopSaving {
|
||||
ArchiveStubFailure(this.stub);
|
||||
class ArchiveStubsFailure implements StopSaving {
|
||||
ArchiveStubsFailure(this.stubs);
|
||||
|
||||
final StubEntity stub;
|
||||
final List<StubEntity> stubs;
|
||||
}
|
||||
|
||||
class DeleteStubRequest implements StartSaving {
|
||||
DeleteStubRequest(this.completer, this.stubId);
|
||||
class DeleteStubsRequest implements StartSaving {
|
||||
DeleteStubsRequest(this.completer, this.stubIds);
|
||||
|
||||
final Completer completer;
|
||||
final String stubId;
|
||||
final List<String> stubIds;
|
||||
}
|
||||
|
||||
class DeleteStubSuccess implements StopSaving, PersistData {
|
||||
DeleteStubSuccess(this.stub);
|
||||
class DeleteStubsSuccess implements StopSaving, PersistData {
|
||||
DeleteStubsSuccess(this.stubs);
|
||||
|
||||
final StubEntity stub;
|
||||
final List<StubEntity> stubs;
|
||||
}
|
||||
|
||||
class DeleteStubFailure implements StopSaving {
|
||||
DeleteStubFailure(this.stub);
|
||||
class DeleteStubsFailure implements StopSaving {
|
||||
DeleteStubsFailure(this.stubs);
|
||||
|
||||
final StubEntity stub;
|
||||
final List<StubEntity> stubs;
|
||||
}
|
||||
|
||||
class RestoreStubRequest implements StartSaving {
|
||||
RestoreStubRequest(this.completer, this.stubId);
|
||||
class RestoreStubsRequest implements StartSaving {
|
||||
RestoreStubsRequest(this.completer, this.stubIds);
|
||||
|
||||
final Completer completer;
|
||||
final String stubId;
|
||||
final List<String> stubIds;
|
||||
}
|
||||
|
||||
class RestoreStubSuccess implements StopSaving, PersistData {
|
||||
RestoreStubSuccess(this.stub);
|
||||
class RestoreStubsSuccess implements StopSaving, PersistData {
|
||||
RestoreStubsSuccess(this.stub);
|
||||
|
||||
final StubEntity stub;
|
||||
final List<StubEntity> stubs;
|
||||
}
|
||||
|
||||
class RestoreStubFailure implements StopSaving {
|
||||
RestoreStubFailure(this.stub);
|
||||
class RestoreStubsFailure implements StopSaving {
|
||||
RestoreStubsFailure(this.stub);
|
||||
|
||||
final StubEntity stub;
|
||||
final List<StubEntity> stubs;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
class FilterStubs implements PersistUI {
|
||||
FilterStubs(this.filter);
|
||||
|
||||
|
|
@ -268,25 +266,26 @@ void handleStubAction(
|
|||
|
||||
final store = StoreProvider.of<AppState>(context);
|
||||
final state = store.state;
|
||||
final CompanyEntity company = state.selectedCompany;
|
||||
final CompanyEntity company = state.company;
|
||||
final localization = AppLocalization.of(context);
|
||||
final stub = stubs.first as StubEntity;
|
||||
final stubIds = stubs.map((stub) => stub.id).toList();
|
||||
|
||||
switch (action) {
|
||||
case EntityAction.edit:
|
||||
store.dispatch(EditStub(context: context, stub: stub));
|
||||
editEntity(context: context, entity: stub);
|
||||
break;
|
||||
case EntityAction.restore:
|
||||
store.dispatch(RestoreStubRequest(
|
||||
snackBarCompleter<Null>(context, localization.restoredStub), stub.id));
|
||||
store.dispatch(RestoreStubsRequest(
|
||||
snackBarCompleter<Null>(context, localization.restoredStub), stubIds));
|
||||
break;
|
||||
case EntityAction.archive:
|
||||
store.dispatch(ArchiveStubRequest(
|
||||
snackBarCompleter<Null>(context, localization.archivedStub), stub.id));
|
||||
store.dispatch(ArchiveStubsRequest(
|
||||
snackBarCompleter<Null>(context, localization.archivedStub), stubIds));
|
||||
break;
|
||||
case EntityAction.delete:
|
||||
store.dispatch(DeleteStubRequest(
|
||||
snackBarCompleter<Null>(context, localization.deletedStub), stub.id));
|
||||
store.dispatch(DeleteStubsRequest(
|
||||
snackBarCompleter<Null>(context, localization.deletedStub), stubIds));
|
||||
break;
|
||||
case EntityAction.toggleMultiselect:
|
||||
if (!store.state.stubListState.isInMultiselect()) {
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ Middleware<AppState> _editStub() {
|
|||
store.dispatch(UpdateCurrentRoute(StubEditScreen.route));
|
||||
|
||||
if (isMobile(action.context)) {
|
||||
action.navigator.pushNamed(QuoteEditScreen.route);
|
||||
action.navigator.pushNamed(StubEditScreen.route);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -105,19 +105,20 @@ Middleware<AppState> _viewStubList() {
|
|||
|
||||
Middleware<AppState> _archiveStub(StubRepository repository) {
|
||||
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
|
||||
final action = dynamicAction as ArchiveStubRequest;
|
||||
final origStub = store.state.stubState.map[action.stubId];
|
||||
final action = dynamicAction as ArchiveStubsRequest;
|
||||
final prevStubs =
|
||||
action.stubIds.map((id) => store.state.stubState.map[id]).toList();
|
||||
repository
|
||||
.saveData(store.state.credentials,
|
||||
origStub, EntityAction.archive)
|
||||
.then((StubEntity stub) {
|
||||
store.dispatch(ArchiveStubSuccess(stub));
|
||||
.bulkAction(
|
||||
store.state.credentials, action.stubIds, EntityAction.archive)
|
||||
.then((List<StubEntity> stubs) {
|
||||
store.dispatch(ArchiveStubsSuccess(stubs));
|
||||
if (action.completer != null) {
|
||||
action.completer.complete(null);
|
||||
}
|
||||
}).catchError((Object error) {
|
||||
print(error);
|
||||
store.dispatch(ArchiveStubFailure(origStub));
|
||||
store.dispatch(ArchiveStubsFailure(prevStubs));
|
||||
if (action.completer != null) {
|
||||
action.completer.completeError(error);
|
||||
}
|
||||
|
|
@ -129,19 +130,20 @@ Middleware<AppState> _archiveStub(StubRepository repository) {
|
|||
|
||||
Middleware<AppState> _deleteStub(StubRepository repository) {
|
||||
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
|
||||
final action = dynamicAction as DeleteStubRequest;
|
||||
final origStub = store.state.stubState.map[action.stubId];
|
||||
final action = dynamicAction as DeleteStubsRequest;
|
||||
final prevStubs =
|
||||
action.stubIds.map((id) => store.state.stubState.map[id]).toList();
|
||||
repository
|
||||
.saveData(store.state.credentials,
|
||||
origStub, EntityAction.delete)
|
||||
.then((StubEntity stub) {
|
||||
store.dispatch(DeleteStubSuccess(stub));
|
||||
.bulkAction(
|
||||
store.state.credentials, action.stubIds, EntityAction.delete)
|
||||
.then((List<StubEntity> stubs) {
|
||||
store.dispatch(DeleteStubsSuccess(stubs));
|
||||
if (action.completer != null) {
|
||||
action.completer.complete(null);
|
||||
}
|
||||
}).catchError((Object error) {
|
||||
print(error);
|
||||
store.dispatch(DeleteStubFailure(origStub));
|
||||
store.dispatch(DeleteStubsFailure(prevStubs));
|
||||
if (action.completer != null) {
|
||||
action.completer.completeError(error);
|
||||
}
|
||||
|
|
@ -153,19 +155,20 @@ Middleware<AppState> _deleteStub(StubRepository repository) {
|
|||
|
||||
Middleware<AppState> _restoreStub(StubRepository repository) {
|
||||
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
|
||||
final action = dynamicAction as RestoreStubRequest;
|
||||
final origStub = store.state.stubState.map[action.stubId];
|
||||
final action = dynamicAction as RestoreStubsRequest;
|
||||
final prevStubs =
|
||||
action.stubIds.map((id) => store.state.stubState.map[id]).toList();
|
||||
repository
|
||||
.saveData(store.state.credentials,
|
||||
origStub, EntityAction.restore)
|
||||
.then((StubEntity stub) {
|
||||
store.dispatch(RestoreStubSuccess(stub));
|
||||
.bulkAction(
|
||||
store.state.credentials, action.stubIds, EntityAction.restore)
|
||||
.then((List<StubEntity> stubs) {
|
||||
store.dispatch(RestoreStubSuccess(stubs));
|
||||
if (action.completer != null) {
|
||||
action.completer.complete(null);
|
||||
}
|
||||
}).catchError((Object error) {
|
||||
print(error);
|
||||
store.dispatch(RestoreStubFailure(origStub));
|
||||
store.dispatch(RestoreStubFailure(prevStubs));
|
||||
if (action.completer != null) {
|
||||
action.completer.completeError(error);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:redux/redux.dart';
|
||||
import 'package:built_collection/built_collection.dart';
|
||||
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
|
||||
import 'package:invoiceninja_flutter/data/models/models.dart';
|
||||
import 'package:invoiceninja_flutter/redux/company/company_actions.dart';
|
||||
|
|
@ -118,7 +119,7 @@ ListUIState _sortStubs(ListUIState stubListState, SortStubs action) {
|
|||
|
||||
ListUIState _startListMultiselect(
|
||||
ListUIState productListState, StartStubMultiselect action) {
|
||||
return productListState.rebuild((b) => b..selectedIds = ListBuilder();
|
||||
return productListState.rebuild((b) => b..selectedIds = ListBuilder());
|
||||
}
|
||||
|
||||
ListUIState _addToListMultiselect(
|
||||
|
|
@ -135,7 +136,7 @@ ListUIState _removeFromListMultiselect(
|
|||
|
||||
ListUIState _clearListMultiselect(
|
||||
ListUIState productListState, ClearStubMultiselect action) {
|
||||
return productListState.rebuild((b) => b..selectedIds = null;
|
||||
return productListState.rebuild((b) => b..selectedIds = null);
|
||||
}
|
||||
|
||||
final stubsReducer = combineReducers<StubState>([
|
||||
|
|
@ -155,58 +156,104 @@ final stubsReducer = combineReducers<StubState>([
|
|||
]);
|
||||
|
||||
StubState _archiveStubRequest(
|
||||
StubState stubState, ArchiveStubRequest action) {
|
||||
final stub = stubState.map[action.stubId]
|
||||
.rebuild((b) => b..archivedAt = DateTime.now().millisecondsSinceEpoch);
|
||||
StubState stubState, ArchiveStubsRequest action) {
|
||||
final stubs = action.stubIds.map((id) => stubState.map[id]).toList();
|
||||
|
||||
return stubState.rebuild((b) => b..map[action.stubId] = stub);
|
||||
for (int i = 0; i < stubs.length; i++) {
|
||||
stubs[i] = stubs[i]
|
||||
.rebuild((b) => b..archivedAt = DateTime.now().millisecondsSinceEpoch);
|
||||
}
|
||||
return stubState.rebuild((b) {
|
||||
for (final stub in stubs) {
|
||||
b.map[stub.id] = stub;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
StubState _archiveStubSuccess(
|
||||
StubState stubState, ArchiveStubSuccess action) {
|
||||
return stubState.rebuild((b) => b..map[action.stub.id] = action.stub);
|
||||
StubState stubState, ArchiveStubsSuccess action) {
|
||||
return stubState.rebuild((b) {
|
||||
for (final stub in action.stubs) {
|
||||
b.map[stub.id] = stub;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
StubState _archiveStubFailure(
|
||||
StubState stubState, ArchiveStubFailure action) {
|
||||
return stubState.rebuild((b) => b..map[action.stub.id] = action.stub);
|
||||
StubState stubState, ArchiveStubsFailure action) {
|
||||
return stubState.rebuild((b) {
|
||||
for (final stub in action.stubs) {
|
||||
b.map[stub.id] = stub;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
StubState _deleteStubRequest(
|
||||
StubState stubState, DeleteStubRequest action) {
|
||||
final stub = stubState.map[action.stubId].rebuild((b) => b
|
||||
..archivedAt = DateTime.now().millisecondsSinceEpoch
|
||||
..isDeleted = true);
|
||||
StubState stubState, DeleteStubsRequest action) {
|
||||
final stubs = action.stubIds.map((id) => stubState.map[id]).toList();
|
||||
|
||||
return stubState.rebuild((b) => b..map[action.stubId] = stub);
|
||||
for (int i = 0; i < stubs.length; i++) {
|
||||
stubs[i] = stubs[i].rebuild((b) => b
|
||||
..archivedAt = DateTime.now().millisecondsSinceEpoch
|
||||
..isDeleted = true);
|
||||
}
|
||||
return stubState.rebuild((b) {
|
||||
for (final stub in stubs) {
|
||||
b.map[stub.id] = stub;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
StubState _deleteStubSuccess(
|
||||
StubState stubState, DeleteStubSuccess action) {
|
||||
return stubState.rebuild((b) => b..map[action.stub.id] = action.stub);
|
||||
StubState stubState, DeleteStubsSuccess action) {
|
||||
return stubState.rebuild((b) {
|
||||
for (final stub in action.stubs) {
|
||||
b.map[stub.id] = stub;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
StubState _deleteStubFailure(
|
||||
StubState stubState, DeleteStubFailure action) {
|
||||
return stubState.rebuild((b) => b..map[action.stub.id] = action.stub);
|
||||
StubState stubState, DeleteStubsFailure action) {
|
||||
return stubState.rebuild((b) {
|
||||
for (final stub in action.stubs) {
|
||||
b.map[stub.id] = stub;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
StubState _restoreStubRequest(
|
||||
StubState stubState, RestoreStubRequest action) {
|
||||
final stub = stubState.map[action.stubId].rebuild((b) => b
|
||||
..archivedAt = null
|
||||
..isDeleted = false);
|
||||
return stubState.rebuild((b) => b..map[action.stubId] = stub);
|
||||
StubState stubState, RestoreStubsRequest action) {
|
||||
final stubs = action.stubIds.map((id) => stubState.map[id]).toList();
|
||||
|
||||
for (int i = 0; i < stubs.length; i++) {
|
||||
stubs[i] = stubs[i].rebuild((b) => b
|
||||
..archivedAt = null
|
||||
..isDeleted = false);
|
||||
}
|
||||
return stubState.rebuild((b) {
|
||||
for (final stub in stubs) {
|
||||
b.map[stub.id] = stub;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
StubState _restoreStubSuccess(
|
||||
StubState stubState, RestoreStubSuccess action) {
|
||||
return stubState.rebuild((b) => b..map[action.stub.id] = action.stub);
|
||||
return stubState.rebuild((b) {
|
||||
for (final stub in action.stubs) {
|
||||
b.map[stub.id] = stub;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
StubState _restoreStubFailure(
|
||||
StubState stubState, RestoreStubFailure action) {
|
||||
return stubState.rebuild((b) => b..map[action.stub.id] = action.stub);
|
||||
return stubState.rebuild((b) {
|
||||
for (final stub in action.stubs) {
|
||||
b.map[stub.id] = stub;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
StubState _addStub(StubState stubState, AddStubSuccess action) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue