This commit is contained in:
Hillel Coren 2019-06-05 18:36:50 +03:00
parent 381adb0315
commit 3000841c1f
10 changed files with 171 additions and 125 deletions

View File

@ -21,6 +21,7 @@ class EntityType extends EnumClass {
static const EntityType task = _$task;
static const EntityType project = _$project;
static const EntityType expense = _$expense;
static const EntityType expenseCategory = _$expenseCategory;
static const EntityType vendor = _$vendor;
static const EntityType vendorContact = _$vendorContact;
static const EntityType credit = _$credit;

View File

@ -29,6 +29,7 @@ const EntityType _$contact = const EntityType._('contact');
const EntityType _$task = const EntityType._('task');
const EntityType _$project = const EntityType._('project');
const EntityType _$expense = const EntityType._('expense');
const EntityType _$expenseCategory = const EntityType._('expenseCategory');
const EntityType _$vendor = const EntityType._('vendor');
const EntityType _$vendorContact = const EntityType._('vendorContact');
const EntityType _$credit = const EntityType._('credit');
@ -63,6 +64,8 @@ EntityType _$typeValueOf(String name) {
return _$project;
case 'expense':
return _$expense;
case 'expenseCategory':
return _$expenseCategory;
case 'vendor':
return _$vendor;
case 'vendorContact':
@ -102,6 +105,7 @@ final BuiltSet<EntityType> _$typeValues =
_$task,
_$project,
_$expense,
_$expenseCategory,
_$vendor,
_$vendorContact,
_$credit,

View File

@ -74,7 +74,6 @@ abstract class ExpenseEntity extends Object
transactionReference: '',
bankId: 0,
expenseCurrencyId: 0,
exchangeCurrencyId: 0,
amount: 0.0,
expenseDate: '',
exchangeRate: 0.0,
@ -85,9 +84,9 @@ abstract class ExpenseEntity extends Object
clientId: 0,
invoiceId: 0,
vendorId: 0,
categoryId: 0,
customValue1: '',
customValue2: '',
expenseCategories: BuiltList<ExpenseCategoryEntity>(),
isDeleted: false,
);
}
@ -126,8 +125,9 @@ abstract class ExpenseEntity extends Object
@BuiltValueField(wireName: 'expense_currency_id')
int get expenseCurrencyId;
@nullable
@BuiltValueField(wireName: 'expense_category_id')
int get exchangeCurrencyId;
int get categoryId;
double get amount;
@ -165,9 +165,6 @@ abstract class ExpenseEntity extends Object
@BuiltValueField(wireName: 'custom_value2')
String get customValue2;
@BuiltValueField(wireName: 'expense_category')
BuiltList<ExpenseCategoryEntity> get expenseCategories;
List<EntityAction> getEntityActions(
{UserEntity user, bool includeEdit = false}) {
final actions = <EntityAction>[];
@ -228,20 +225,36 @@ abstract class ExpenseEntity extends Object
static Serializer<ExpenseEntity> get serializer => _$expenseEntitySerializer;
}
class ExpenseCategoryFields {
static const String name = 'name';
}
abstract class ExpenseCategoryEntity extends Object
with BaseEntity, SelectableEntity
implements Built<ExpenseCategoryEntity, ExpenseCategoryEntityBuilder> {
factory ExpenseCategoryEntity(
[void updates(ExpenseCategoryEntityBuilder b)]) = _$ExpenseCategoryEntity;
factory ExpenseCategoryEntity() {
return _$ExpenseCategoryEntity._(
id: --ExpenseCategoryEntity.counter,
name: '',
isDeleted: false,
);
}
ExpenseCategoryEntity._();
static int counter = 0;
@override
bool matchesFilter(String filter) {
if (filter == null || filter.isEmpty) {
return true;
}
filter = filter.toLowerCase();
if (name.toLowerCase().contains(filter)) {
return true;
}
return false;
}
@ -256,7 +269,7 @@ abstract class ExpenseCategoryEntity extends Object
@override
String get listDisplayName {
return '';
return name;
}
@override
@ -267,6 +280,22 @@ abstract class ExpenseCategoryEntity extends Object
String get name;
int compareTo(
ExpenseCategoryEntity category, String sortField, bool sortAscending) {
int response = 0;
final ExpenseCategoryEntity categoryA = sortAscending ? this : category;
final ExpenseCategoryEntity categoryB = sortAscending ? category : this;
switch (sortField) {
case ExpenseCategoryFields.name:
response = categoryA.name
.toLowerCase()
.compareTo(categoryB.name.toLowerCase());
}
return response;
}
static Serializer<ExpenseCategoryEntity> get serializer =>
_$expenseCategoryEntitySerializer;
}

View File

@ -149,9 +149,6 @@ class _$ExpenseEntitySerializer implements StructuredSerializer<ExpenseEntity> {
'expense_currency_id',
serializers.serialize(object.expenseCurrencyId,
specifiedType: const FullType(int)),
'expense_category_id',
serializers.serialize(object.exchangeCurrencyId,
specifiedType: const FullType(int)),
'amount',
serializers.serialize(object.amount,
specifiedType: const FullType(double)),
@ -188,11 +185,13 @@ class _$ExpenseEntitySerializer implements StructuredSerializer<ExpenseEntity> {
'custom_value2',
serializers.serialize(object.customValue2,
specifiedType: const FullType(String)),
'expense_category',
serializers.serialize(object.expenseCategories,
specifiedType: const FullType(
BuiltList, const [const FullType(ExpenseCategoryEntity)])),
];
if (object.categoryId != null) {
result
..add('expense_category_id')
..add(serializers.serialize(object.categoryId,
specifiedType: const FullType(int)));
}
if (object.createdAt != null) {
result
..add('created_at')
@ -273,7 +272,7 @@ class _$ExpenseEntitySerializer implements StructuredSerializer<ExpenseEntity> {
specifiedType: const FullType(int)) as int;
break;
case 'expense_category_id':
result.exchangeCurrencyId = serializers.deserialize(value,
result.categoryId = serializers.deserialize(value,
specifiedType: const FullType(int)) as int;
break;
case 'amount':
@ -324,12 +323,6 @@ class _$ExpenseEntitySerializer implements StructuredSerializer<ExpenseEntity> {
result.customValue2 = serializers.deserialize(value,
specifiedType: const FullType(String)) as String;
break;
case 'expense_category':
result.expenseCategories.replace(serializers.deserialize(value,
specifiedType: const FullType(
BuiltList, const [const FullType(ExpenseCategoryEntity)]))
as BuiltList);
break;
case 'created_at':
result.createdAt = serializers.deserialize(value,
specifiedType: const FullType(int)) as int;
@ -666,7 +659,7 @@ class _$ExpenseEntity extends ExpenseEntity {
@override
final int expenseCurrencyId;
@override
final int exchangeCurrencyId;
final int categoryId;
@override
final double amount;
@override
@ -692,8 +685,6 @@ class _$ExpenseEntity extends ExpenseEntity {
@override
final String customValue2;
@override
final BuiltList<ExpenseCategoryEntity> expenseCategories;
@override
final int createdAt;
@override
final int updatedAt;
@ -717,7 +708,7 @@ class _$ExpenseEntity extends ExpenseEntity {
this.transactionReference,
this.bankId,
this.expenseCurrencyId,
this.exchangeCurrencyId,
this.categoryId,
this.amount,
this.expenseDate,
this.exchangeRate,
@ -730,7 +721,6 @@ class _$ExpenseEntity extends ExpenseEntity {
this.vendorId,
this.customValue1,
this.customValue2,
this.expenseCategories,
this.createdAt,
this.updatedAt,
this.archivedAt,
@ -760,9 +750,6 @@ class _$ExpenseEntity extends ExpenseEntity {
if (expenseCurrencyId == null) {
throw new BuiltValueNullFieldError('ExpenseEntity', 'expenseCurrencyId');
}
if (exchangeCurrencyId == null) {
throw new BuiltValueNullFieldError('ExpenseEntity', 'exchangeCurrencyId');
}
if (amount == null) {
throw new BuiltValueNullFieldError('ExpenseEntity', 'amount');
}
@ -799,9 +786,6 @@ class _$ExpenseEntity extends ExpenseEntity {
if (customValue2 == null) {
throw new BuiltValueNullFieldError('ExpenseEntity', 'customValue2');
}
if (expenseCategories == null) {
throw new BuiltValueNullFieldError('ExpenseEntity', 'expenseCategories');
}
}
@override
@ -822,7 +806,7 @@ class _$ExpenseEntity extends ExpenseEntity {
transactionReference == other.transactionReference &&
bankId == other.bankId &&
expenseCurrencyId == other.expenseCurrencyId &&
exchangeCurrencyId == other.exchangeCurrencyId &&
categoryId == other.categoryId &&
amount == other.amount &&
expenseDate == other.expenseDate &&
exchangeRate == other.exchangeRate &&
@ -835,7 +819,6 @@ class _$ExpenseEntity extends ExpenseEntity {
vendorId == other.vendorId &&
customValue1 == other.customValue1 &&
customValue2 == other.customValue2 &&
expenseCategories == other.expenseCategories &&
createdAt == other.createdAt &&
updatedAt == other.updatedAt &&
archivedAt == other.archivedAt &&
@ -864,20 +847,20 @@ class _$ExpenseEntity extends ExpenseEntity {
$jc(
$jc(
$jc(
$jc($jc($jc($jc($jc($jc($jc($jc($jc(0, privateNotes.hashCode), publicNotes.hashCode), shouldBeInvoiced.hashCode), transactionId.hashCode), transactionReference.hashCode), bankId.hashCode), expenseCurrencyId.hashCode), exchangeCurrencyId.hashCode),
amount.hashCode),
expenseDate.hashCode),
exchangeRate.hashCode),
invoiceCurrencyId.hashCode),
taxName1.hashCode),
taxRate1.hashCode),
taxRate2.hashCode),
clientId.hashCode),
invoiceId.hashCode),
vendorId.hashCode),
customValue1.hashCode),
customValue2.hashCode),
expenseCategories.hashCode),
$jc($jc($jc($jc($jc($jc($jc($jc(0, privateNotes.hashCode), publicNotes.hashCode), shouldBeInvoiced.hashCode), transactionId.hashCode), transactionReference.hashCode), bankId.hashCode), expenseCurrencyId.hashCode),
categoryId.hashCode),
amount.hashCode),
expenseDate.hashCode),
exchangeRate.hashCode),
invoiceCurrencyId.hashCode),
taxName1.hashCode),
taxRate1.hashCode),
taxRate2.hashCode),
clientId.hashCode),
invoiceId.hashCode),
vendorId.hashCode),
customValue1.hashCode),
customValue2.hashCode),
createdAt.hashCode),
updatedAt.hashCode),
archivedAt.hashCode),
@ -896,7 +879,7 @@ class _$ExpenseEntity extends ExpenseEntity {
..add('transactionReference', transactionReference)
..add('bankId', bankId)
..add('expenseCurrencyId', expenseCurrencyId)
..add('exchangeCurrencyId', exchangeCurrencyId)
..add('categoryId', categoryId)
..add('amount', amount)
..add('expenseDate', expenseDate)
..add('exchangeRate', exchangeRate)
@ -909,7 +892,6 @@ class _$ExpenseEntity extends ExpenseEntity {
..add('vendorId', vendorId)
..add('customValue1', customValue1)
..add('customValue2', customValue2)
..add('expenseCategories', expenseCategories)
..add('createdAt', createdAt)
..add('updatedAt', updatedAt)
..add('archivedAt', archivedAt)
@ -956,10 +938,9 @@ class ExpenseEntityBuilder
set expenseCurrencyId(int expenseCurrencyId) =>
_$this._expenseCurrencyId = expenseCurrencyId;
int _exchangeCurrencyId;
int get exchangeCurrencyId => _$this._exchangeCurrencyId;
set exchangeCurrencyId(int exchangeCurrencyId) =>
_$this._exchangeCurrencyId = exchangeCurrencyId;
int _categoryId;
int get categoryId => _$this._categoryId;
set categoryId(int categoryId) => _$this._categoryId = categoryId;
double _amount;
double get amount => _$this._amount;
@ -1010,12 +991,6 @@ class ExpenseEntityBuilder
String get customValue2 => _$this._customValue2;
set customValue2(String customValue2) => _$this._customValue2 = customValue2;
ListBuilder<ExpenseCategoryEntity> _expenseCategories;
ListBuilder<ExpenseCategoryEntity> get expenseCategories =>
_$this._expenseCategories ??= new ListBuilder<ExpenseCategoryEntity>();
set expenseCategories(ListBuilder<ExpenseCategoryEntity> expenseCategories) =>
_$this._expenseCategories = expenseCategories;
int _createdAt;
int get createdAt => _$this._createdAt;
set createdAt(int createdAt) => _$this._createdAt = createdAt;
@ -1051,7 +1026,7 @@ class ExpenseEntityBuilder
_transactionReference = _$v.transactionReference;
_bankId = _$v.bankId;
_expenseCurrencyId = _$v.expenseCurrencyId;
_exchangeCurrencyId = _$v.exchangeCurrencyId;
_categoryId = _$v.categoryId;
_amount = _$v.amount;
_expenseDate = _$v.expenseDate;
_exchangeRate = _$v.exchangeRate;
@ -1064,7 +1039,6 @@ class ExpenseEntityBuilder
_vendorId = _$v.vendorId;
_customValue1 = _$v.customValue1;
_customValue2 = _$v.customValue2;
_expenseCategories = _$v.expenseCategories?.toBuilder();
_createdAt = _$v.createdAt;
_updatedAt = _$v.updatedAt;
_archivedAt = _$v.archivedAt;
@ -1091,48 +1065,34 @@ class ExpenseEntityBuilder
@override
_$ExpenseEntity build() {
_$ExpenseEntity _$result;
try {
_$result = _$v ??
new _$ExpenseEntity._(
privateNotes: privateNotes,
publicNotes: publicNotes,
shouldBeInvoiced: shouldBeInvoiced,
transactionId: transactionId,
transactionReference: transactionReference,
bankId: bankId,
expenseCurrencyId: expenseCurrencyId,
exchangeCurrencyId: exchangeCurrencyId,
amount: amount,
expenseDate: expenseDate,
exchangeRate: exchangeRate,
invoiceCurrencyId: invoiceCurrencyId,
taxName1: taxName1,
taxRate1: taxRate1,
taxRate2: taxRate2,
clientId: clientId,
invoiceId: invoiceId,
vendorId: vendorId,
customValue1: customValue1,
customValue2: customValue2,
expenseCategories: expenseCategories.build(),
createdAt: createdAt,
updatedAt: updatedAt,
archivedAt: archivedAt,
isDeleted: isDeleted,
isOwner: isOwner,
id: id);
} catch (_) {
String _$failedField;
try {
_$failedField = 'expenseCategories';
expenseCategories.build();
} catch (e) {
throw new BuiltValueNestedFieldError(
'ExpenseEntity', _$failedField, e.toString());
}
rethrow;
}
final _$result = _$v ??
new _$ExpenseEntity._(
privateNotes: privateNotes,
publicNotes: publicNotes,
shouldBeInvoiced: shouldBeInvoiced,
transactionId: transactionId,
transactionReference: transactionReference,
bankId: bankId,
expenseCurrencyId: expenseCurrencyId,
categoryId: categoryId,
amount: amount,
expenseDate: expenseDate,
exchangeRate: exchangeRate,
invoiceCurrencyId: invoiceCurrencyId,
taxName1: taxName1,
taxRate1: taxRate1,
taxRate2: taxRate2,
clientId: clientId,
invoiceId: invoiceId,
vendorId: vendorId,
customValue1: customValue1,
customValue2: customValue2,
createdAt: createdAt,
updatedAt: updatedAt,
archivedAt: archivedAt,
isDeleted: isDeleted,
isOwner: isOwner,
id: id);
replace(_$result);
return _$result;
}

View File

@ -248,10 +248,6 @@ Serializers _$serializers = (new Serializers().toBuilder()
..addBuilderFactory(
const FullType(BuiltList, const [const FullType(String)]),
() => new ListBuilder<String>())
..addBuilderFactory(
const FullType(
BuiltList, const [const FullType(ExpenseCategoryEntity)]),
() => new ListBuilder<ExpenseCategoryEntity>())
..addBuilderFactory(
const FullType(BuiltList, const [const FullType(ExpenseEntity)]),
() => new ListBuilder<ExpenseEntity>())
@ -310,8 +306,10 @@ Serializers _$serializers = (new Serializers().toBuilder()
BuiltList, const [const FullType(ExpenseCategoryEntity)]),
() => new ListBuilder<ExpenseCategoryEntity>())
..addBuilderFactory(
const FullType(BuiltMap,
const [const FullType(int), const FullType(ExpenseCategoryEntity)]),
const FullType(BuiltMap, const [
const FullType(int),
const FullType(ExpenseCategoryEntity)
]),
() => new MapBuilder<int, ExpenseCategoryEntity>())
..addBuilderFactory(
const FullType(
@ -335,10 +333,12 @@ Serializers _$serializers = (new Serializers().toBuilder()
BuiltMap, const [const FullType(String), const FullType(bool)]),
() => new MapBuilder<String, bool>())
..addBuilderFactory(
const FullType(
BuiltMap, const [const FullType(int), const FullType(ClientEntity)]),
const FullType(BuiltMap,
const [const FullType(int), const FullType(ClientEntity)]),
() => new MapBuilder<int, ClientEntity>())
..addBuilderFactory(const FullType(BuiltList, const [const FullType(int)]), () => new ListBuilder<int>())
..addBuilderFactory(
const FullType(BuiltList, const [const FullType(int)]),
() => new ListBuilder<int>())
..addBuilderFactory(const FullType(BuiltMap, const [const FullType(int), const FullType(CurrencyEntity)]), () => new MapBuilder<int, CurrencyEntity>())
..addBuilderFactory(const FullType(BuiltMap, const [const FullType(int), const FullType(SizeEntity)]), () => new MapBuilder<int, SizeEntity>())
..addBuilderFactory(const FullType(BuiltMap, const [const FullType(int), const FullType(IndustryEntity)]), () => new MapBuilder<int, IndustryEntity>())

View File

@ -190,7 +190,7 @@ abstract class AppState implements Built<AppState, AppStateBuilder> {
@override
String toString() {
//return 'Is Loading: ${this.isLoading}, Invoice: ${this.invoiceUIState.selected}';
return 'Expense Categories: ${selectedCompany.expenseCategories}';
//return 'Route: ${uiState.currentRoute}';
//return 'Expense Categories: ${selectedCompany.expenseCategories}';
return 'Route: ${uiState.currentRoute}';
}
}

View File

@ -47,17 +47,28 @@ Reducer<CompanyEntity> companyEntityReducer = combineReducers([
CompanyEntity loadCompanySuccessReducer(
CompanyEntity company, LoadCompanySuccess action) {
if (action.company.taskStatuses == null) {
return action.company;
} else {
return action.company.rebuild((b) => b
var company = action.company;
if (company.taskStatuses != null) {
company = company.rebuild((b) => b
..taskStatusMap.addAll(Map.fromIterable(
action.company.taskStatuses,
company.taskStatuses,
key: (dynamic item) => item.id,
value: (dynamic item) => item,
)));
}
if (company.expenseCategories != null) {
company = company.rebuild((b) => b
..expenseCategoryMap.addAll(Map.fromIterable(
company.expenseCategories,
key: (dynamic item) => item.id,
value: (dynamic item) => item,
)));
}
return company;
/*
return action.company.rebuild((b) => b
..userMap.addAll(Map.fromIterable(

View File

@ -5,6 +5,29 @@ import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/company/company_state.dart';
import 'package:memoize/memoize.dart';
var memoizedDropdownExpenseCategoriesList = memo2(
(BuiltMap<int, ExpenseCategoryEntity> categoryMap,
BuiltList<ExpenseCategoryEntity> categoryList) =>
dropdownExpenseCategoriesSelector(categoryMap, categoryList));
List<int> dropdownExpenseCategoriesSelector(
BuiltMap<int, ExpenseCategoryEntity> categoryMap,
BuiltList<ExpenseCategoryEntity> categoryList) {
final list = categoryList
//.where((category) => category.isActive)
.map((category) => category.id)
.toList();
list.sort((categoryAId, categoryBId) {
final categoryA = categoryMap[categoryAId];
final categoryB = categoryMap[categoryBId];
return categoryA.compareTo(categoryB, ExpenseCategoryFields.name, true);
});
return list;
}
var memoizedHasMultipleCurrencies = memo2(
(CompanyEntity company, BuiltMap<int, ClientEntity> clientMap) =>
hasMultipleCurrencies(company, clientMap));

View File

@ -8,6 +8,7 @@ import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/ui/app/form_card.dart';
import 'package:invoiceninja_flutter/redux/static/static_selectors.dart';
import 'package:invoiceninja_flutter/redux/vendor/vendor_selectors.dart';
import 'package:invoiceninja_flutter/redux/company/company_selectors.dart';
class ExpenseEditDetails extends StatefulWidget {
const ExpenseEditDetails({
@ -89,9 +90,6 @@ class ExpenseEditDetailsState extends State<ExpenseEditDetails> {
entityMap: vendorState.map,
entityList:
memoizedDropdownVendorList(vendorState.map, vendorState.list),
validator: (String val) => val.trim().isEmpty
? AppLocalization.of(context).pleaseSelectAClient
: null,
onSelected: (vendor) {
viewModel
.onChanged(expense.rebuild((b) => b..vendorId = vendor.id));
@ -100,6 +98,23 @@ class ExpenseEditDetailsState extends State<ExpenseEditDetails> {
//viewModel.onAddVendorPressed(context, completer);
},
),
EntityDropdown(
entityType: EntityType.expenseCategory,
labelText: localization.category,
initialValue: (company.expenseCategoryMap[expense.categoryId] ??
ExpenseCategoryEntity())
.name,
entityMap: company.expenseCategoryMap,
entityList: memoizedDropdownExpenseCategoriesList(
company.expenseCategoryMap, company.expenseCategories),
onSelected: (category) {
viewModel
.onChanged(expense.rebuild((b) => b..categoryId = category.id));
},
onAddPressed: (completer) {
//viewModel.onAddVendorPressed(context, completer);
},
),
EntityDropdown(
entityType: EntityType.currency,
entityMap: staticState.currencyMap,

View File

@ -20,6 +20,7 @@ class AppLocalization {
static final Map<String, Map<String, String>> _localizedValues = {
'en': {
'category': 'Category',
'address': 'Address',
'new_vendor': 'New Vendor',
'created_vendor': 'Successfully created vendor',
@ -12278,6 +12279,8 @@ class AppLocalization {
String get address => _localizedValues[locale.toString()]['address'];
String get category => _localizedValues[locale.toString()]['category'];
String lookup(String key) {
final lookupKey = toSnakeCase(key);
return _localizedValues[locale.toString()][lookupKey] ??