Add support for task statuses

This commit is contained in:
Hillel Coren 2019-02-26 21:07:29 +02:00
parent 310cc7e754
commit f42232d0ed
11 changed files with 181 additions and 25 deletions

View File

@ -22,8 +22,8 @@ Note: the mobile app requires the latest version of the web app.
- [x] Invoices
- [x] Quotes
- [x] Payments
- [ ] Projects
- [ ] Tasks
- [x] Projects
- [x] Tasks
- [ ] Vendors
- [ ] Expenses
- [ ] Credits

View File

@ -49,6 +49,7 @@ abstract class CompanyEntity
customPaymentTerms: BuiltList<PaymentTermEntity>(),
taxRates: BuiltList<TaxRateEntity>(),
taskStatuses: BuiltList<TaskStatusEntity>(),
taskStatusMap: BuiltMap<int, TaskStatusEntity>(),
user: UserEntity(),
//userId: 0,
//users: BuiltList<UserEntity>(),
@ -187,6 +188,7 @@ abstract class CompanyEntity
@nullable
@BuiltValueField(wireName: 'task_statuses')
BuiltList<TaskStatusEntity> get taskStatuses;
BuiltMap<int, TaskStatusEntity> get taskStatusMap;
//@BuiltValueField(wireName: 'user_id')
//int get userId;

View File

@ -147,6 +147,10 @@ class _$CompanyEntitySerializer implements StructuredSerializer<CompanyEntity> {
serializers.serialize(object.taxRates,
specifiedType:
const FullType(BuiltList, const [const FullType(TaxRateEntity)])),
'taskStatusMap',
serializers.serialize(object.taskStatusMap,
specifiedType: const FullType(BuiltMap,
const [const FullType(int), const FullType(TaskStatusEntity)])),
'user',
serializers.serialize(object.user,
specifiedType: const FullType(UserEntity)),
@ -391,6 +395,13 @@ class _$CompanyEntitySerializer implements StructuredSerializer<CompanyEntity> {
BuiltList, const [const FullType(TaskStatusEntity)]))
as BuiltList);
break;
case 'taskStatusMap':
result.taskStatusMap.replace(serializers.deserialize(value,
specifiedType: const FullType(BuiltMap, const [
const FullType(int),
const FullType(TaskStatusEntity)
])) as BuiltMap);
break;
case 'user':
result.user.replace(serializers.deserialize(value,
specifiedType: const FullType(UserEntity)) as UserEntity);
@ -770,6 +781,8 @@ class _$CompanyEntity extends CompanyEntity {
@override
final BuiltList<TaskStatusEntity> taskStatuses;
@override
final BuiltMap<int, TaskStatusEntity> taskStatusMap;
@override
final UserEntity user;
@override
final BuiltMap<String, String> customFields;
@ -850,6 +863,7 @@ class _$CompanyEntity extends CompanyEntity {
this.enableCustomInvoiceTaxes2,
this.taxRates,
this.taskStatuses,
this.taskStatusMap,
this.user,
this.customFields,
this.customPaymentTerms,
@ -994,6 +1008,9 @@ class _$CompanyEntity extends CompanyEntity {
if (taxRates == null) {
throw new BuiltValueNullFieldError('CompanyEntity', 'taxRates');
}
if (taskStatusMap == null) {
throw new BuiltValueNullFieldError('CompanyEntity', 'taskStatusMap');
}
if (user == null) {
throw new BuiltValueNullFieldError('CompanyEntity', 'user');
}
@ -1101,6 +1118,7 @@ class _$CompanyEntity extends CompanyEntity {
enableCustomInvoiceTaxes2 == other.enableCustomInvoiceTaxes2 &&
taxRates == other.taxRates &&
taskStatuses == other.taskStatuses &&
taskStatusMap == other.taskStatusMap &&
user == other.user &&
customFields == other.customFields &&
customPaymentTerms == other.customPaymentTerms &&
@ -1142,7 +1160,7 @@ class _$CompanyEntity extends CompanyEntity {
$jc(
$jc(
$jc(
$jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc(0, name.hashCode), token.hashCode), plan.hashCode), logoUrl.hashCode), appUrl.hashCode), companyCurrencyId.hashCode), timezoneId.hashCode), countryId.hashCode), dateFormatId.hashCode), datetimeFormatId.hashCode), defaultInvoiceTerms.hashCode), enableInvoiceTaxes.hashCode), enableInvoiceItemTaxes.hashCode), defaultInvoiceDesignId.hashCode), defaultQuoteDesignId.hashCode), languageId.hashCode), defaultInvoiceFooter.hashCode), showInvoiceItemTaxes.hashCode), enableMilitaryTime.hashCode), defaultTaxName1.hashCode), defaultTaxRate1.hashCode), defaultTaxName2.hashCode), defaultTaxRate2.hashCode), defaultQuoteTerms.hashCode), showCurrencyCode.hashCode), enableSecondTaxRate.hashCode), startOfWeek.hashCode), financialYearStart.hashCode), enabledModules.hashCode), defaultPaymentTerms.hashCode), defaultPaymentTypeId.hashCode), defaultTaskRate.hashCode), enableInclusiveTaxes.hashCode), convertProductExchangeRate.hashCode), enableCustomInvoiceTaxes1.hashCode), enableCustomInvoiceTaxes2.hashCode), taxRates.hashCode), taskStatuses.hashCode),
$jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc(0, name.hashCode), token.hashCode), plan.hashCode), logoUrl.hashCode), appUrl.hashCode), companyCurrencyId.hashCode), timezoneId.hashCode), countryId.hashCode), dateFormatId.hashCode), datetimeFormatId.hashCode), defaultInvoiceTerms.hashCode), enableInvoiceTaxes.hashCode), enableInvoiceItemTaxes.hashCode), defaultInvoiceDesignId.hashCode), defaultQuoteDesignId.hashCode), languageId.hashCode), defaultInvoiceFooter.hashCode), showInvoiceItemTaxes.hashCode), enableMilitaryTime.hashCode), defaultTaxName1.hashCode), defaultTaxRate1.hashCode), defaultTaxName2.hashCode), defaultTaxRate2.hashCode), defaultQuoteTerms.hashCode), showCurrencyCode.hashCode), enableSecondTaxRate.hashCode), startOfWeek.hashCode), financialYearStart.hashCode), enabledModules.hashCode), defaultPaymentTerms.hashCode), defaultPaymentTypeId.hashCode), defaultTaskRate.hashCode), enableInclusiveTaxes.hashCode), convertProductExchangeRate.hashCode), enableCustomInvoiceTaxes1.hashCode), enableCustomInvoiceTaxes2.hashCode), taxRates.hashCode), taskStatuses.hashCode), taskStatusMap.hashCode),
user.hashCode),
customFields.hashCode),
customPaymentTerms.hashCode),
@ -1205,6 +1223,7 @@ class _$CompanyEntity extends CompanyEntity {
..add('enableCustomInvoiceTaxes2', enableCustomInvoiceTaxes2)
..add('taxRates', taxRates)
..add('taskStatuses', taskStatuses)
..add('taskStatusMap', taskStatusMap)
..add('user', user)
..add('customFields', customFields)
..add('customPaymentTerms', customPaymentTerms)
@ -1414,6 +1433,12 @@ class CompanyEntityBuilder
set taskStatuses(ListBuilder<TaskStatusEntity> taskStatuses) =>
_$this._taskStatuses = taskStatuses;
MapBuilder<int, TaskStatusEntity> _taskStatusMap;
MapBuilder<int, TaskStatusEntity> get taskStatusMap =>
_$this._taskStatusMap ??= new MapBuilder<int, TaskStatusEntity>();
set taskStatusMap(MapBuilder<int, TaskStatusEntity> taskStatusMap) =>
_$this._taskStatusMap = taskStatusMap;
UserEntityBuilder _user;
UserEntityBuilder get user => _$this._user ??= new UserEntityBuilder();
set user(UserEntityBuilder user) => _$this._user = user;
@ -1550,6 +1575,7 @@ class CompanyEntityBuilder
_enableCustomInvoiceTaxes2 = _$v.enableCustomInvoiceTaxes2;
_taxRates = _$v.taxRates?.toBuilder();
_taskStatuses = _$v.taskStatuses?.toBuilder();
_taskStatusMap = _$v.taskStatusMap?.toBuilder();
_user = _$v.user?.toBuilder();
_customFields = _$v.customFields?.toBuilder();
_customPaymentTerms = _$v.customPaymentTerms?.toBuilder();
@ -1631,6 +1657,7 @@ class CompanyEntityBuilder
enableCustomInvoiceTaxes2: enableCustomInvoiceTaxes2,
taxRates: taxRates.build(),
taskStatuses: _taskStatuses?.build(),
taskStatusMap: taskStatusMap.build(),
user: user.build(),
customFields: customFields.build(),
customPaymentTerms: customPaymentTerms.build(),
@ -1657,6 +1684,8 @@ class CompanyEntityBuilder
taxRates.build();
_$failedField = 'taskStatuses';
_taskStatuses?.build();
_$failedField = 'taskStatusMap';
taskStatusMap.build();
_$failedField = 'user';
user.build();
_$failedField = 'customFields';

View File

@ -30,6 +30,7 @@ class EntityType extends EnumClass {
static const EntityType industry = _$industry;
static const EntityType size = _$size;
static const EntityType paymentType = _$paymentType;
static const EntityType taskStatus = _$taskStatus;
String get plural {
return toString() + 's';

View File

@ -38,6 +38,7 @@ const EntityType _$language = const EntityType._('language');
const EntityType _$industry = const EntityType._('industry');
const EntityType _$size = const EntityType._('size');
const EntityType _$paymentType = const EntityType._('paymentType');
const EntityType _$taskStatus = const EntityType._('taskStatus');
EntityType _$typeValueOf(String name) {
switch (name) {
@ -79,6 +80,8 @@ EntityType _$typeValueOf(String name) {
return _$size;
case 'paymentType':
return _$paymentType;
case 'taskStatus':
return _$taskStatus;
default:
throw new ArgumentError(name);
}
@ -105,6 +108,7 @@ final BuiltSet<EntityType> _$typeValues =
_$industry,
_$size,
_$paymentType,
_$taskStatus,
]);
const EntityState _$active = const EntityState._('active');

View File

@ -297,6 +297,10 @@ Serializers _$serializers = (new Serializers().toBuilder()
..addBuilderFactory(
const FullType(BuiltList, const [const FullType(TaskStatusEntity)]),
() => new ListBuilder<TaskStatusEntity>())
..addBuilderFactory(
const FullType(BuiltMap,
const [const FullType(int), const FullType(TaskStatusEntity)]),
() => new MapBuilder<int, TaskStatusEntity>())
..addBuilderFactory(
const FullType(
BuiltMap, const [const FullType(String), const FullType(String)]),
@ -337,14 +341,11 @@ Serializers _$serializers = (new Serializers().toBuilder()
const FullType(BuiltMap,
const [const FullType(int), const FullType(IndustryEntity)]),
() => new MapBuilder<int, IndustryEntity>())
..addBuilderFactory(
const FullType(BuiltMap,
const [const FullType(int), const FullType(TimezoneEntity)]),
() => new MapBuilder<int, TimezoneEntity>())
..addBuilderFactory(
const FullType(
BuiltMap, const [const FullType(int), const FullType(DateFormatEntity)]),
() => new MapBuilder<int, DateFormatEntity>())
BuiltMap, const [const FullType(int), const FullType(TimezoneEntity)]),
() => new MapBuilder<int, TimezoneEntity>())
..addBuilderFactory(const FullType(BuiltMap, const [const FullType(int), const FullType(DateFormatEntity)]), () => new MapBuilder<int, DateFormatEntity>())
..addBuilderFactory(const FullType(BuiltMap, const [const FullType(int), const FullType(DatetimeFormatEntity)]), () => new MapBuilder<int, DatetimeFormatEntity>())
..addBuilderFactory(const FullType(BuiltMap, const [const FullType(int), const FullType(LanguageEntity)]), () => new MapBuilder<int, LanguageEntity>())
..addBuilderFactory(const FullType(BuiltMap, const [const FullType(int), const FullType(PaymentTypeEntity)]), () => new MapBuilder<int, PaymentTypeEntity>())

View File

@ -346,6 +346,15 @@ abstract class TaskEntity extends Object
@BuiltValueField(wireName: 'custom_value2')
String get customValue2;
@nullable
@BuiltValueField(wireName: 'task_status_id')
int get taskStatusId;
@nullable
@BuiltValueField(wireName: 'task_status_sort_order')
int get taskStatusSortOrder;
List<EntityAction> getEntityActions(
{UserEntity user, ClientEntity client, bool includeEdit = false}) {
final actions = <EntityAction>[];
@ -449,17 +458,24 @@ abstract class TaskEntity extends Object
}
abstract class TaskStatusEntity extends Object
with EntityStatus
with EntityStatus, SelectableEntity
implements Built<TaskStatusEntity, TaskStatusEntityBuilder> {
factory TaskStatusEntity() {
return _$TaskStatusEntity._(
id: 0,
name: '',
sortOrder: 0,
);
}
TaskStatusEntity._();
@BuiltValueField(wireName: 'sort_order')
int get sortOrder;
@override
String get listDisplayName => name;
static Serializer<TaskStatusEntity> get serializer =>
_$taskStatusEntitySerializer;
}

View File

@ -209,6 +209,18 @@ class _$TaskEntitySerializer implements StructuredSerializer<TaskEntity> {
..add(serializers.serialize(object.projectId,
specifiedType: const FullType(int)));
}
if (object.taskStatusId != null) {
result
..add('task_status_id')
..add(serializers.serialize(object.taskStatusId,
specifiedType: const FullType(int)));
}
if (object.taskStatusSortOrder != null) {
result
..add('task_status_sort_order')
..add(serializers.serialize(object.taskStatusSortOrder,
specifiedType: const FullType(int)));
}
if (object.createdAt != null) {
result
..add('created_at')
@ -296,6 +308,14 @@ class _$TaskEntitySerializer implements StructuredSerializer<TaskEntity> {
result.customValue2 = serializers.deserialize(value,
specifiedType: const FullType(String)) as String;
break;
case 'task_status_id':
result.taskStatusId = serializers.deserialize(value,
specifiedType: const FullType(int)) as int;
break;
case 'task_status_sort_order':
result.taskStatusSortOrder = serializers.deserialize(value,
specifiedType: const FullType(int)) as int;
break;
case 'created_at':
result.createdAt = serializers.deserialize(value,
specifiedType: const FullType(int)) as int;
@ -338,6 +358,9 @@ class _$TaskStatusEntitySerializer
Iterable serialize(Serializers serializers, TaskStatusEntity object,
{FullType specifiedType = FullType.unspecified}) {
final result = <Object>[
'sort_order',
serializers.serialize(object.sortOrder,
specifiedType: const FullType(int)),
'id',
serializers.serialize(object.id, specifiedType: const FullType(int)),
'name',
@ -358,6 +381,10 @@ class _$TaskStatusEntitySerializer
iterator.moveNext();
final dynamic value = iterator.current;
switch (key) {
case 'sort_order':
result.sortOrder = serializers.deserialize(value,
specifiedType: const FullType(int)) as int;
break;
case 'id':
result.id = serializers.deserialize(value,
specifiedType: const FullType(int)) as int;
@ -664,6 +691,10 @@ class _$TaskEntity extends TaskEntity {
@override
final String customValue2;
@override
final int taskStatusId;
@override
final int taskStatusSortOrder;
@override
final int createdAt;
@override
final int updatedAt;
@ -689,6 +720,8 @@ class _$TaskEntity extends TaskEntity {
this.isRunning,
this.customValue1,
this.customValue2,
this.taskStatusId,
this.taskStatusSortOrder,
this.createdAt,
this.updatedAt,
this.archivedAt,
@ -736,6 +769,8 @@ class _$TaskEntity extends TaskEntity {
isRunning == other.isRunning &&
customValue1 == other.customValue1 &&
customValue2 == other.customValue2 &&
taskStatusId == other.taskStatusId &&
taskStatusSortOrder == other.taskStatusSortOrder &&
createdAt == other.createdAt &&
updatedAt == other.updatedAt &&
archivedAt == other.archivedAt &&
@ -761,17 +796,23 @@ class _$TaskEntity extends TaskEntity {
$jc(
$jc(
$jc(
0,
description
$jc(
$jc(
0,
description
.hashCode),
duration
.hashCode),
invoiceId
.hashCode),
duration.hashCode),
invoiceId.hashCode),
clientId.hashCode),
projectId.hashCode),
timeLog.hashCode),
isRunning.hashCode),
customValue1.hashCode),
customValue2.hashCode),
clientId.hashCode),
projectId.hashCode),
timeLog.hashCode),
isRunning.hashCode),
customValue1.hashCode),
customValue2.hashCode),
taskStatusId.hashCode),
taskStatusSortOrder.hashCode),
createdAt.hashCode),
updatedAt.hashCode),
archivedAt.hashCode),
@ -792,6 +833,8 @@ class _$TaskEntity extends TaskEntity {
..add('isRunning', isRunning)
..add('customValue1', customValue1)
..add('customValue2', customValue2)
..add('taskStatusId', taskStatusId)
..add('taskStatusSortOrder', taskStatusSortOrder)
..add('createdAt', createdAt)
..add('updatedAt', updatedAt)
..add('archivedAt', archivedAt)
@ -841,6 +884,15 @@ class TaskEntityBuilder implements Builder<TaskEntity, TaskEntityBuilder> {
String get customValue2 => _$this._customValue2;
set customValue2(String customValue2) => _$this._customValue2 = customValue2;
int _taskStatusId;
int get taskStatusId => _$this._taskStatusId;
set taskStatusId(int taskStatusId) => _$this._taskStatusId = taskStatusId;
int _taskStatusSortOrder;
int get taskStatusSortOrder => _$this._taskStatusSortOrder;
set taskStatusSortOrder(int taskStatusSortOrder) =>
_$this._taskStatusSortOrder = taskStatusSortOrder;
int _createdAt;
int get createdAt => _$this._createdAt;
set createdAt(int createdAt) => _$this._createdAt = createdAt;
@ -878,6 +930,8 @@ class TaskEntityBuilder implements Builder<TaskEntity, TaskEntityBuilder> {
_isRunning = _$v.isRunning;
_customValue1 = _$v.customValue1;
_customValue2 = _$v.customValue2;
_taskStatusId = _$v.taskStatusId;
_taskStatusSortOrder = _$v.taskStatusSortOrder;
_createdAt = _$v.createdAt;
_updatedAt = _$v.updatedAt;
_archivedAt = _$v.archivedAt;
@ -915,6 +969,8 @@ class TaskEntityBuilder implements Builder<TaskEntity, TaskEntityBuilder> {
isRunning: isRunning,
customValue1: customValue1,
customValue2: customValue2,
taskStatusId: taskStatusId,
taskStatusSortOrder: taskStatusSortOrder,
createdAt: createdAt,
updatedAt: updatedAt,
archivedAt: archivedAt,
@ -927,6 +983,8 @@ class TaskEntityBuilder implements Builder<TaskEntity, TaskEntityBuilder> {
}
class _$TaskStatusEntity extends TaskStatusEntity {
@override
final int sortOrder;
@override
final int id;
@override
@ -935,7 +993,10 @@ class _$TaskStatusEntity extends TaskStatusEntity {
factory _$TaskStatusEntity([void updates(TaskStatusEntityBuilder b)]) =>
(new TaskStatusEntityBuilder()..update(updates)).build();
_$TaskStatusEntity._({this.id, this.name}) : super._() {
_$TaskStatusEntity._({this.sortOrder, this.id, this.name}) : super._() {
if (sortOrder == null) {
throw new BuiltValueNullFieldError('TaskStatusEntity', 'sortOrder');
}
if (id == null) {
throw new BuiltValueNullFieldError('TaskStatusEntity', 'id');
}
@ -955,17 +1016,22 @@ class _$TaskStatusEntity extends TaskStatusEntity {
@override
bool operator ==(Object other) {
if (identical(other, this)) return true;
return other is TaskStatusEntity && id == other.id && name == other.name;
return other is TaskStatusEntity &&
sortOrder == other.sortOrder &&
id == other.id &&
name == other.name;
}
@override
int get hashCode {
return $jf($jc($jc(0, id.hashCode), name.hashCode));
return $jf(
$jc($jc($jc(0, sortOrder.hashCode), id.hashCode), name.hashCode));
}
@override
String toString() {
return (newBuiltValueToStringHelper('TaskStatusEntity')
..add('sortOrder', sortOrder)
..add('id', id)
..add('name', name))
.toString();
@ -976,6 +1042,10 @@ class TaskStatusEntityBuilder
implements Builder<TaskStatusEntity, TaskStatusEntityBuilder> {
_$TaskStatusEntity _$v;
int _sortOrder;
int get sortOrder => _$this._sortOrder;
set sortOrder(int sortOrder) => _$this._sortOrder = sortOrder;
int _id;
int get id => _$this._id;
set id(int id) => _$this._id = id;
@ -988,6 +1058,7 @@ class TaskStatusEntityBuilder
TaskStatusEntityBuilder get _$this {
if (_$v != null) {
_sortOrder = _$v.sortOrder;
_id = _$v.id;
_name = _$v.name;
_$v = null;
@ -1010,7 +1081,8 @@ class TaskStatusEntityBuilder
@override
_$TaskStatusEntity build() {
final _$result = _$v ?? new _$TaskStatusEntity._(id: id, name: name);
final _$result = _$v ??
new _$TaskStatusEntity._(sortOrder: sortOrder, id: id, name: name);
replace(_$result);
return _$result;
}

View File

@ -41,7 +41,18 @@ Reducer<CompanyEntity> companyEntityReducer = combineReducers([
CompanyEntity loadCompanySuccessReducer(
CompanyEntity company, LoadCompanySuccess action) {
return action.company;
if (action.company.taskStatuses == null) {
return action.company;
} else {
return action.company.rebuild((b) => b
..taskStatusMap.addAll(Map.fromIterable(
action.company.taskStatuses,
key: (dynamic item) => item.id,
value: (dynamic item) => item,
))
);
}
/*
return action.company.rebuild((b) => b

View File

@ -126,6 +126,21 @@ class _TaskEditDetailsState extends State<TaskEditDetails> {
},
)
: SizedBox(),
EntityDropdown(
entityType: EntityType.taskStatus,
labelText: localization.status,
initialValue: (company.taskStatusMap[task.taskStatusId] ??
TaskStatusEntity())
.name,
entityMap: company.taskStatusMap,
entityList: company.taskStatusMap.keys.toList(),
onSelected: (selected) {
final taskStatus = selected as TaskStatusEntity;
viewModel.onChanged(task.rebuild((b) => b
..taskStatusId = taskStatus.id
..taskStatusSortOrder = 9999));
},
),
TextFormField(
maxLines: 4,
controller: _descriptionController,

View File

@ -56,6 +56,11 @@ class _TaskViewState extends State<TaskView> {
final Map<String, String> fields = {};
if ((task.taskStatusId ?? 0) > 0) {
fields[localization.status] =
company.taskStatusMap[task.taskStatusId].name ?? '';
}
if (task.customValue1.isNotEmpty) {
final label1 = company.getCustomFieldLabel(CustomFieldType.task1);
fields[label1] = task.customValue1;