Schedules

This commit is contained in:
Hillel Coren 2023-02-14 17:13:18 +02:00
parent 5edf9461e6
commit 50b3e30462
41 changed files with 3714 additions and 8 deletions

View File

@ -156,6 +156,7 @@ abstract class CompanyEntity extends Object
bankAccounts: BuiltList<BankAccountEntity>(),
transactions: BuiltList<TransactionEntity>(),
transactionRules: BuiltList<TransactionRuleEntity>(),
schedules: BuiltList<ScheduleEntity>(),
);
}
@ -372,6 +373,8 @@ abstract class CompanyEntity extends Object
BuiltList<DocumentEntity> get documents;
BuiltList<ScheduleEntity> get schedules;
@BuiltValueField(wireName: 'tokens_hashed')
BuiltList<TokenEntity> get tokens;
@ -734,7 +737,8 @@ abstract class CompanyEntity extends Object
..purchaseOrders.replace(BuiltList<InvoiceEntity>())
..bankAccounts.replace(BuiltList<BankAccountEntity>())
..transactions.replace(BuiltList<TransactionEntity>())
..transactionRules.replace(BuiltList<TransactionRuleEntity>());
..transactionRules.replace(BuiltList<TransactionRuleEntity>())
..schedules.replace(BuiltList<ScheduleEntity>());
static Serializer<CompanyEntity> get serializer => _$companyEntitySerializer;
}

View File

@ -282,6 +282,10 @@ class _$CompanyEntitySerializer implements StructuredSerializer<CompanyEntity> {
serializers.serialize(object.documents,
specifiedType: const FullType(
BuiltList, const [const FullType(DocumentEntity)])),
'schedules',
serializers.serialize(object.schedules,
specifiedType: const FullType(
BuiltList, const [const FullType(ScheduleEntity)])),
'tokens_hashed',
serializers.serialize(object.tokens,
specifiedType:
@ -775,6 +779,12 @@ class _$CompanyEntitySerializer implements StructuredSerializer<CompanyEntity> {
BuiltList, const [const FullType(DocumentEntity)]))
as BuiltList<Object>);
break;
case 'schedules':
result.schedules.replace(serializers.deserialize(value,
specifiedType: const FullType(
BuiltList, const [const FullType(ScheduleEntity)]))
as BuiltList<Object>);
break;
case 'tokens_hashed':
result.tokens.replace(serializers.deserialize(value,
specifiedType: const FullType(
@ -1747,6 +1757,8 @@ class _$CompanyEntity extends CompanyEntity {
@override
final BuiltList<DocumentEntity> documents;
@override
final BuiltList<ScheduleEntity> schedules;
@override
final BuiltList<TokenEntity> tokens;
@override
final BuiltList<WebhookEntity> webhooks;
@ -1894,6 +1906,7 @@ class _$CompanyEntity extends CompanyEntity {
this.vendors,
this.designs,
this.documents,
this.schedules,
this.tokens,
this.webhooks,
this.subscriptions,
@ -2066,6 +2079,8 @@ class _$CompanyEntity extends CompanyEntity {
BuiltValueNullFieldError.checkNotNull(designs, 'CompanyEntity', 'designs');
BuiltValueNullFieldError.checkNotNull(
documents, 'CompanyEntity', 'documents');
BuiltValueNullFieldError.checkNotNull(
schedules, 'CompanyEntity', 'schedules');
BuiltValueNullFieldError.checkNotNull(tokens, 'CompanyEntity', 'tokens');
BuiltValueNullFieldError.checkNotNull(
webhooks, 'CompanyEntity', 'webhooks');
@ -2210,6 +2225,7 @@ class _$CompanyEntity extends CompanyEntity {
vendors == other.vendors &&
designs == other.designs &&
documents == other.documents &&
schedules == other.schedules &&
tokens == other.tokens &&
webhooks == other.webhooks &&
subscriptions == other.subscriptions &&
@ -2268,7 +2284,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($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($jc($jc($jc($jc($jc($jc($jc($jc($jc(0, enableCustomSurchargeTaxes1.hashCode), enableCustomSurchargeTaxes2.hashCode), enableCustomSurchargeTaxes3.hashCode), enableCustomSurchargeTaxes4.hashCode), sizeId.hashCode), industryId.hashCode), subdomain.hashCode), portalMode.hashCode), portalDomain.hashCode), updateProducts.hashCode), convertProductExchangeRate.hashCode), convertRateToClient.hashCode), fillProducts.hashCode), enableProductCost.hashCode), enableProductQuantity.hashCode), enableProductDiscount.hashCode), defaultTaskIsDateBased.hashCode), defaultQuantity.hashCode), showProductDetails.hashCode), clientCanRegister.hashCode), isLarge.hashCode), isDisabled.hashCode), enableShopApi.hashCode), companyKey.hashCode), firstDayOfWeek.hashCode), firstMonthOfYear.hashCode), numberOfInvoiceTaxRates.hashCode), numberOfItemTaxRates.hashCode), numberOfExpenseTaxRates.hashCode), expenseInclusiveTaxes.hashCode), sessionTimeout.hashCode), passwordTimeout.hashCode), oauthPasswordRequired.hashCode), markdownEnabled.hashCode), markdownEmailEnabled.hashCode), useCommaAsDecimalPlace.hashCode), reportIncludeDrafts.hashCode), reportIncludeDeleted.hashCode), useQuoteTermsOnConversion.hashCode), enableApplyingPayments.hashCode), trackInventory.hashCode), stockNotificationThreshold.hashCode), stockNotification.hashCode), invoiceTaskLock.hashCode), convertPaymentCurrency.hashCode), convertExpenseCurrency.hashCode), notifyVendorWhenPaid.hashCode), groups.hashCode), activities.hashCode), taxRates.hashCode), taskStatuses.hashCode), taskStatusMap.hashCode), companyGateways.hashCode), expenseCategories.hashCode), users.hashCode), clients.hashCode), products.hashCode), invoices.hashCode), recurringInvoices.hashCode), recurringExpenses.hashCode), payments.hashCode), quotes.hashCode), credits.hashCode), purchaseOrders.hashCode), bankAccounts.hashCode), transactions.hashCode), transactionRules.hashCode), tasks.hashCode), projects.hashCode), expenses.hashCode), vendors.hashCode), designs.hashCode), documents.hashCode), tokens.hashCode), webhooks.hashCode), subscriptions.hashCode), paymentTerms.hashCode), systemLogs.hashCode), clientRegistrationFields.hashCode), customFields.hashCode), slackWebhookUrl.hashCode), googleAnalyticsKey.hashCode), matomoUrl.hashCode), matomoId.hashCode), markExpensesInvoiceable.hashCode), markExpensesPaid.hashCode), invoiceExpenseDocuments.hashCode), invoiceTaskDocuments.hashCode), invoiceTaskTimelog.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($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($jc($jc($jc($jc($jc($jc($jc($jc($jc(0, enableCustomSurchargeTaxes1.hashCode), enableCustomSurchargeTaxes2.hashCode), enableCustomSurchargeTaxes3.hashCode), enableCustomSurchargeTaxes4.hashCode), sizeId.hashCode), industryId.hashCode), subdomain.hashCode), portalMode.hashCode), portalDomain.hashCode), updateProducts.hashCode), convertProductExchangeRate.hashCode), convertRateToClient.hashCode), fillProducts.hashCode), enableProductCost.hashCode), enableProductQuantity.hashCode), enableProductDiscount.hashCode), defaultTaskIsDateBased.hashCode), defaultQuantity.hashCode), showProductDetails.hashCode), clientCanRegister.hashCode), isLarge.hashCode), isDisabled.hashCode), enableShopApi.hashCode), companyKey.hashCode), firstDayOfWeek.hashCode), firstMonthOfYear.hashCode), numberOfInvoiceTaxRates.hashCode), numberOfItemTaxRates.hashCode), numberOfExpenseTaxRates.hashCode), expenseInclusiveTaxes.hashCode), sessionTimeout.hashCode), passwordTimeout.hashCode), oauthPasswordRequired.hashCode), markdownEnabled.hashCode), markdownEmailEnabled.hashCode), useCommaAsDecimalPlace.hashCode), reportIncludeDrafts.hashCode), reportIncludeDeleted.hashCode), useQuoteTermsOnConversion.hashCode), enableApplyingPayments.hashCode), trackInventory.hashCode), stockNotificationThreshold.hashCode), stockNotification.hashCode), invoiceTaskLock.hashCode), convertPaymentCurrency.hashCode), convertExpenseCurrency.hashCode), notifyVendorWhenPaid.hashCode), groups.hashCode), activities.hashCode), taxRates.hashCode), taskStatuses.hashCode), taskStatusMap.hashCode), companyGateways.hashCode), expenseCategories.hashCode), users.hashCode), clients.hashCode), products.hashCode), invoices.hashCode), recurringInvoices.hashCode), recurringExpenses.hashCode), payments.hashCode), quotes.hashCode), credits.hashCode), purchaseOrders.hashCode), bankAccounts.hashCode), transactions.hashCode), transactionRules.hashCode), tasks.hashCode), projects.hashCode), expenses.hashCode), vendors.hashCode), designs.hashCode), documents.hashCode), schedules.hashCode), tokens.hashCode), webhooks.hashCode), subscriptions.hashCode), paymentTerms.hashCode), systemLogs.hashCode), clientRegistrationFields.hashCode), customFields.hashCode), slackWebhookUrl.hashCode), googleAnalyticsKey.hashCode), matomoUrl.hashCode), matomoId.hashCode), markExpensesInvoiceable.hashCode), markExpensesPaid.hashCode), invoiceExpenseDocuments.hashCode), invoiceTaskDocuments.hashCode), invoiceTaskTimelog.hashCode),
invoiceTaskDatelog.hashCode),
invoiceTaskProject.hashCode),
invoiceTaskHours.hashCode),
@ -2366,6 +2382,7 @@ class _$CompanyEntity extends CompanyEntity {
..add('vendors', vendors)
..add('designs', designs)
..add('documents', documents)
..add('schedules', schedules)
..add('tokens', tokens)
..add('webhooks', webhooks)
..add('subscriptions', subscriptions)
@ -2783,6 +2800,12 @@ class CompanyEntityBuilder
set documents(ListBuilder<DocumentEntity> documents) =>
_$this._documents = documents;
ListBuilder<ScheduleEntity> _schedules;
ListBuilder<ScheduleEntity> get schedules =>
_$this._schedules ??= new ListBuilder<ScheduleEntity>();
set schedules(ListBuilder<ScheduleEntity> schedules) =>
_$this._schedules = schedules;
ListBuilder<TokenEntity> _tokens;
ListBuilder<TokenEntity> get tokens =>
_$this._tokens ??= new ListBuilder<TokenEntity>();
@ -3037,6 +3060,7 @@ class CompanyEntityBuilder
_vendors = $v.vendors.toBuilder();
_designs = $v.designs.toBuilder();
_documents = $v.documents.toBuilder();
_schedules = $v.schedules.toBuilder();
_tokens = $v.tokens.toBuilder();
_webhooks = $v.webhooks.toBuilder();
_subscriptions = $v.subscriptions.toBuilder();
@ -3181,6 +3205,7 @@ class CompanyEntityBuilder
vendors: vendors.build(),
designs: designs.build(),
documents: documents.build(),
schedules: schedules.build(),
tokens: tokens.build(),
webhooks: webhooks.build(),
subscriptions: subscriptions.build(),
@ -3271,6 +3296,8 @@ class CompanyEntityBuilder
designs.build();
_$failedField = 'documents';
documents.build();
_$failedField = 'schedules';
schedules.build();
_$failedField = 'tokens';
tokens.build();
_$failedField = 'webhooks';

View File

@ -42,6 +42,7 @@ class EntityType extends EnumClass {
static const EntityType invoiceItem = _$invoiceItem;
static const EntityType design = _$design;
// STARTER: entity type - do not remove comment
static const EntityType schedule = _$schedule;
static const EntityType transactionRule = _$transactionRule;
static const EntityType transaction = _$transaction;
static const EntityType bankAccount = _$bankAccount;
@ -90,6 +91,7 @@ class EntityType extends EnumClass {
EntityType.subscription,
EntityType.bankAccount,
EntityType.transactionRule,
EntityType.schedule,
].contains(this);
List<EntityType> get relatedTypes {

View File

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

View File

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

View File

@ -0,0 +1,207 @@
import 'package:built_value/built_value.dart';
import 'package:built_collection/built_collection.dart';
import 'package:built_value/serializer.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/utils/formatting.dart';
import 'package:invoiceninja_flutter/utils/strings.dart';
part 'schedule_model.g.dart';
abstract class ScheduleListResponse
implements Built<ScheduleListResponse, ScheduleListResponseBuilder> {
factory ScheduleListResponse([void updates(ScheduleListResponseBuilder b)]) =
_$ScheduleListResponse;
ScheduleListResponse._();
@override
@memoized
int get hashCode;
BuiltList<ScheduleEntity> get data;
static Serializer<ScheduleListResponse> get serializer =>
_$scheduleListResponseSerializer;
}
abstract class ScheduleItemResponse
implements Built<ScheduleItemResponse, ScheduleItemResponseBuilder> {
factory ScheduleItemResponse([void updates(ScheduleItemResponseBuilder b)]) =
_$ScheduleItemResponse;
ScheduleItemResponse._();
@override
@memoized
int get hashCode;
ScheduleEntity get data;
static Serializer<ScheduleItemResponse> get serializer =>
_$scheduleItemResponseSerializer;
}
class ScheduleFields {
// STARTER: fields - do not remove comment
static const String name = 'name';
}
abstract class ScheduleEntity extends Object
with BaseEntity
implements Built<ScheduleEntity, ScheduleEntityBuilder> {
factory ScheduleEntity({String id, AppState state}) {
return _$ScheduleEntity._(
id: id ?? BaseEntity.nextId,
isChanged: false,
isDeleted: false,
createdAt: 0,
updatedAt: 0,
createdUserId: '',
assignedUserId: '',
archivedAt: 0,
frequencyId: '5',
isPaused: false,
name: '',
nextRun: '',
template: '',
);
}
ScheduleEntity._();
@override
@memoized
int get hashCode;
String get name;
@BuiltValueField(wireName: 'frequency_id')
String get frequencyId;
@BuiltValueField(wireName: 'next_run')
String get nextRun;
String get template;
@BuiltValueField(wireName: 'is_paused')
bool get isPaused;
ScheduleParameters get parameters;
@override
EntityType get entityType => EntityType.schedule;
@override
List<EntityAction> getActions(
{UserCompanyEntity userCompany,
ClientEntity client,
bool includeEdit = false,
bool multiselect = false}) {
final actions = <EntityAction>[];
if (!isDeleted &&
!multiselect &&
includeEdit &&
userCompany.canEditEntity(this)) {
actions.add(EntityAction.edit);
}
if (actions.isNotEmpty && actions.last != null) {
actions.add(null);
}
return actions..addAll(super.getActions(userCompany: userCompany));
}
int compareTo(ScheduleEntity schedule, String sortField, bool sortAscending) {
int response = 0;
final scheduleA = sortAscending ? this : schedule;
final scheduleB = sortAscending ? schedule : this;
switch (sortField) {
// STARTER: sort switch - do not remove comment
case ScheduleFields.name:
response = scheduleA.name.compareTo(scheduleB.name);
break;
default:
print('## ERROR: sort by schedule.$sortField is not implemented');
break;
}
if (response == 0) {
// STARTER: sort default - do not remove comment
return scheduleA.name.compareTo(scheduleB.name);
} else {
return response;
}
}
@override
bool matchesFilter(String filter) {
return matchesStrings(
haystacks: [
//
],
needle: filter,
);
}
@override
String matchesFilterValue(String filter) {
return matchesStringsValue(
haystacks: [
//
],
needle: filter,
);
}
@override
String get listDisplayName => null;
@override
double get listDisplayAmount => null;
@override
FormatNumberType get listDisplayAmountType => null;
static Serializer<ScheduleEntity> get serializer =>
_$scheduleEntitySerializer;
}
abstract class ScheduleParameters
implements Built<ScheduleParameters, ScheduleParametersBuilder> {
factory ScheduleParameters({String id, bool isEnabled}) {
return _$ScheduleParameters._(
//maxLimit: -1,
);
}
ScheduleParameters._();
@override
@memoized
int get hashCode;
@BuiltValueField(wireName: 'date_range')
String get dateRange;
@BuiltValueField(wireName: 'show_payments_table')
bool get showPaymentsTable;
@BuiltValueField(wireName: 'show_aging_table')
bool get showAgingTable;
String get status;
BuiltList<String> get clients;
// ignore: unused_element
//static void _initializeBuilder(ScheduleParametersBuilder builder) =>
// builder..isEnabled = false;
static Serializer<ScheduleParameters> get serializer =>
_$scheduleParametersSerializer;
}

View File

@ -0,0 +1,973 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'schedule_model.dart';
// **************************************************************************
// BuiltValueGenerator
// **************************************************************************
Serializer<ScheduleListResponse> _$scheduleListResponseSerializer =
new _$ScheduleListResponseSerializer();
Serializer<ScheduleItemResponse> _$scheduleItemResponseSerializer =
new _$ScheduleItemResponseSerializer();
Serializer<ScheduleEntity> _$scheduleEntitySerializer =
new _$ScheduleEntitySerializer();
Serializer<ScheduleParameters> _$scheduleParametersSerializer =
new _$ScheduleParametersSerializer();
class _$ScheduleListResponseSerializer
implements StructuredSerializer<ScheduleListResponse> {
@override
final Iterable<Type> types = const [
ScheduleListResponse,
_$ScheduleListResponse
];
@override
final String wireName = 'ScheduleListResponse';
@override
Iterable<Object> serialize(
Serializers serializers, ScheduleListResponse object,
{FullType specifiedType = FullType.unspecified}) {
final result = <Object>[
'data',
serializers.serialize(object.data,
specifiedType: const FullType(
BuiltList, const [const FullType(ScheduleEntity)])),
];
return result;
}
@override
ScheduleListResponse deserialize(
Serializers serializers, Iterable<Object> serialized,
{FullType specifiedType = FullType.unspecified}) {
final result = new ScheduleListResponseBuilder();
final iterator = serialized.iterator;
while (iterator.moveNext()) {
final key = iterator.current as String;
iterator.moveNext();
final Object value = iterator.current;
switch (key) {
case 'data':
result.data.replace(serializers.deserialize(value,
specifiedType: const FullType(
BuiltList, const [const FullType(ScheduleEntity)]))
as BuiltList<Object>);
break;
}
}
return result.build();
}
}
class _$ScheduleItemResponseSerializer
implements StructuredSerializer<ScheduleItemResponse> {
@override
final Iterable<Type> types = const [
ScheduleItemResponse,
_$ScheduleItemResponse
];
@override
final String wireName = 'ScheduleItemResponse';
@override
Iterable<Object> serialize(
Serializers serializers, ScheduleItemResponse object,
{FullType specifiedType = FullType.unspecified}) {
final result = <Object>[
'data',
serializers.serialize(object.data,
specifiedType: const FullType(ScheduleEntity)),
];
return result;
}
@override
ScheduleItemResponse deserialize(
Serializers serializers, Iterable<Object> serialized,
{FullType specifiedType = FullType.unspecified}) {
final result = new ScheduleItemResponseBuilder();
final iterator = serialized.iterator;
while (iterator.moveNext()) {
final key = iterator.current as String;
iterator.moveNext();
final Object value = iterator.current;
switch (key) {
case 'data':
result.data.replace(serializers.deserialize(value,
specifiedType: const FullType(ScheduleEntity)) as ScheduleEntity);
break;
}
}
return result.build();
}
}
class _$ScheduleEntitySerializer
implements StructuredSerializer<ScheduleEntity> {
@override
final Iterable<Type> types = const [ScheduleEntity, _$ScheduleEntity];
@override
final String wireName = 'ScheduleEntity';
@override
Iterable<Object> serialize(Serializers serializers, ScheduleEntity object,
{FullType specifiedType = FullType.unspecified}) {
final result = <Object>[
'name',
serializers.serialize(object.name, specifiedType: const FullType(String)),
'frequency_id',
serializers.serialize(object.frequencyId,
specifiedType: const FullType(String)),
'next_run',
serializers.serialize(object.nextRun,
specifiedType: const FullType(String)),
'template',
serializers.serialize(object.template,
specifiedType: const FullType(String)),
'is_paused',
serializers.serialize(object.isPaused,
specifiedType: const FullType(bool)),
'parameters',
serializers.serialize(object.parameters,
specifiedType: const FullType(ScheduleParameters)),
'created_at',
serializers.serialize(object.createdAt,
specifiedType: const FullType(int)),
'updated_at',
serializers.serialize(object.updatedAt,
specifiedType: const FullType(int)),
'archived_at',
serializers.serialize(object.archivedAt,
specifiedType: const FullType(int)),
'id',
serializers.serialize(object.id, specifiedType: const FullType(String)),
];
Object value;
value = object.isChanged;
if (value != null) {
result
..add('isChanged')
..add(
serializers.serialize(value, specifiedType: const FullType(bool)));
}
value = object.isDeleted;
if (value != null) {
result
..add('is_deleted')
..add(
serializers.serialize(value, specifiedType: const FullType(bool)));
}
value = object.createdUserId;
if (value != null) {
result
..add('user_id')
..add(serializers.serialize(value,
specifiedType: const FullType(String)));
}
value = object.assignedUserId;
if (value != null) {
result
..add('assigned_user_id')
..add(serializers.serialize(value,
specifiedType: const FullType(String)));
}
return result;
}
@override
ScheduleEntity deserialize(
Serializers serializers, Iterable<Object> serialized,
{FullType specifiedType = FullType.unspecified}) {
final result = new ScheduleEntityBuilder();
final iterator = serialized.iterator;
while (iterator.moveNext()) {
final key = iterator.current as String;
iterator.moveNext();
final Object value = iterator.current;
switch (key) {
case 'name':
result.name = serializers.deserialize(value,
specifiedType: const FullType(String)) as String;
break;
case 'frequency_id':
result.frequencyId = serializers.deserialize(value,
specifiedType: const FullType(String)) as String;
break;
case 'next_run':
result.nextRun = serializers.deserialize(value,
specifiedType: const FullType(String)) as String;
break;
case 'template':
result.template = serializers.deserialize(value,
specifiedType: const FullType(String)) as String;
break;
case 'is_paused':
result.isPaused = serializers.deserialize(value,
specifiedType: const FullType(bool)) as bool;
break;
case 'parameters':
result.parameters.replace(serializers.deserialize(value,
specifiedType: const FullType(ScheduleParameters))
as ScheduleParameters);
break;
case 'isChanged':
result.isChanged = serializers.deserialize(value,
specifiedType: const FullType(bool)) as bool;
break;
case 'created_at':
result.createdAt = serializers.deserialize(value,
specifiedType: const FullType(int)) as int;
break;
case 'updated_at':
result.updatedAt = serializers.deserialize(value,
specifiedType: const FullType(int)) as int;
break;
case 'archived_at':
result.archivedAt = serializers.deserialize(value,
specifiedType: const FullType(int)) as int;
break;
case 'is_deleted':
result.isDeleted = serializers.deserialize(value,
specifiedType: const FullType(bool)) as bool;
break;
case 'user_id':
result.createdUserId = serializers.deserialize(value,
specifiedType: const FullType(String)) as String;
break;
case 'assigned_user_id':
result.assignedUserId = serializers.deserialize(value,
specifiedType: const FullType(String)) as String;
break;
case 'id':
result.id = serializers.deserialize(value,
specifiedType: const FullType(String)) as String;
break;
}
}
return result.build();
}
}
class _$ScheduleParametersSerializer
implements StructuredSerializer<ScheduleParameters> {
@override
final Iterable<Type> types = const [ScheduleParameters, _$ScheduleParameters];
@override
final String wireName = 'ScheduleParameters';
@override
Iterable<Object> serialize(Serializers serializers, ScheduleParameters object,
{FullType specifiedType = FullType.unspecified}) {
final result = <Object>[
'date_range',
serializers.serialize(object.dateRange,
specifiedType: const FullType(String)),
'show_payments_table',
serializers.serialize(object.showPaymentsTable,
specifiedType: const FullType(bool)),
'show_aging_table',
serializers.serialize(object.showAgingTable,
specifiedType: const FullType(bool)),
'status',
serializers.serialize(object.status,
specifiedType: const FullType(String)),
'clients',
serializers.serialize(object.clients,
specifiedType:
const FullType(BuiltList, const [const FullType(String)])),
];
return result;
}
@override
ScheduleParameters deserialize(
Serializers serializers, Iterable<Object> serialized,
{FullType specifiedType = FullType.unspecified}) {
final result = new ScheduleParametersBuilder();
final iterator = serialized.iterator;
while (iterator.moveNext()) {
final key = iterator.current as String;
iterator.moveNext();
final Object value = iterator.current;
switch (key) {
case 'date_range':
result.dateRange = serializers.deserialize(value,
specifiedType: const FullType(String)) as String;
break;
case 'show_payments_table':
result.showPaymentsTable = serializers.deserialize(value,
specifiedType: const FullType(bool)) as bool;
break;
case 'show_aging_table':
result.showAgingTable = serializers.deserialize(value,
specifiedType: const FullType(bool)) as bool;
break;
case 'status':
result.status = serializers.deserialize(value,
specifiedType: const FullType(String)) as String;
break;
case 'clients':
result.clients.replace(serializers.deserialize(value,
specifiedType:
const FullType(BuiltList, const [const FullType(String)]))
as BuiltList<Object>);
break;
}
}
return result.build();
}
}
class _$ScheduleListResponse extends ScheduleListResponse {
@override
final BuiltList<ScheduleEntity> data;
factory _$ScheduleListResponse(
[void Function(ScheduleListResponseBuilder) updates]) =>
(new ScheduleListResponseBuilder()..update(updates)).build();
_$ScheduleListResponse._({this.data}) : super._() {
BuiltValueNullFieldError.checkNotNull(data, 'ScheduleListResponse', 'data');
}
@override
ScheduleListResponse rebuild(
void Function(ScheduleListResponseBuilder) updates) =>
(toBuilder()..update(updates)).build();
@override
ScheduleListResponseBuilder toBuilder() =>
new ScheduleListResponseBuilder()..replace(this);
@override
bool operator ==(Object other) {
if (identical(other, this)) return true;
return other is ScheduleListResponse && data == other.data;
}
int __hashCode;
@override
int get hashCode {
return __hashCode ??= $jf($jc(0, data.hashCode));
}
@override
String toString() {
return (newBuiltValueToStringHelper('ScheduleListResponse')
..add('data', data))
.toString();
}
}
class ScheduleListResponseBuilder
implements Builder<ScheduleListResponse, ScheduleListResponseBuilder> {
_$ScheduleListResponse _$v;
ListBuilder<ScheduleEntity> _data;
ListBuilder<ScheduleEntity> get data =>
_$this._data ??= new ListBuilder<ScheduleEntity>();
set data(ListBuilder<ScheduleEntity> data) => _$this._data = data;
ScheduleListResponseBuilder();
ScheduleListResponseBuilder get _$this {
final $v = _$v;
if ($v != null) {
_data = $v.data.toBuilder();
_$v = null;
}
return this;
}
@override
void replace(ScheduleListResponse other) {
ArgumentError.checkNotNull(other, 'other');
_$v = other as _$ScheduleListResponse;
}
@override
void update(void Function(ScheduleListResponseBuilder) updates) {
if (updates != null) updates(this);
}
@override
_$ScheduleListResponse build() {
_$ScheduleListResponse _$result;
try {
_$result = _$v ?? new _$ScheduleListResponse._(data: data.build());
} catch (_) {
String _$failedField;
try {
_$failedField = 'data';
data.build();
} catch (e) {
throw new BuiltValueNestedFieldError(
'ScheduleListResponse', _$failedField, e.toString());
}
rethrow;
}
replace(_$result);
return _$result;
}
}
class _$ScheduleItemResponse extends ScheduleItemResponse {
@override
final ScheduleEntity data;
factory _$ScheduleItemResponse(
[void Function(ScheduleItemResponseBuilder) updates]) =>
(new ScheduleItemResponseBuilder()..update(updates)).build();
_$ScheduleItemResponse._({this.data}) : super._() {
BuiltValueNullFieldError.checkNotNull(data, 'ScheduleItemResponse', 'data');
}
@override
ScheduleItemResponse rebuild(
void Function(ScheduleItemResponseBuilder) updates) =>
(toBuilder()..update(updates)).build();
@override
ScheduleItemResponseBuilder toBuilder() =>
new ScheduleItemResponseBuilder()..replace(this);
@override
bool operator ==(Object other) {
if (identical(other, this)) return true;
return other is ScheduleItemResponse && data == other.data;
}
int __hashCode;
@override
int get hashCode {
return __hashCode ??= $jf($jc(0, data.hashCode));
}
@override
String toString() {
return (newBuiltValueToStringHelper('ScheduleItemResponse')
..add('data', data))
.toString();
}
}
class ScheduleItemResponseBuilder
implements Builder<ScheduleItemResponse, ScheduleItemResponseBuilder> {
_$ScheduleItemResponse _$v;
ScheduleEntityBuilder _data;
ScheduleEntityBuilder get data =>
_$this._data ??= new ScheduleEntityBuilder();
set data(ScheduleEntityBuilder data) => _$this._data = data;
ScheduleItemResponseBuilder();
ScheduleItemResponseBuilder get _$this {
final $v = _$v;
if ($v != null) {
_data = $v.data.toBuilder();
_$v = null;
}
return this;
}
@override
void replace(ScheduleItemResponse other) {
ArgumentError.checkNotNull(other, 'other');
_$v = other as _$ScheduleItemResponse;
}
@override
void update(void Function(ScheduleItemResponseBuilder) updates) {
if (updates != null) updates(this);
}
@override
_$ScheduleItemResponse build() {
_$ScheduleItemResponse _$result;
try {
_$result = _$v ?? new _$ScheduleItemResponse._(data: data.build());
} catch (_) {
String _$failedField;
try {
_$failedField = 'data';
data.build();
} catch (e) {
throw new BuiltValueNestedFieldError(
'ScheduleItemResponse', _$failedField, e.toString());
}
rethrow;
}
replace(_$result);
return _$result;
}
}
class _$ScheduleEntity extends ScheduleEntity {
@override
final String name;
@override
final String frequencyId;
@override
final String nextRun;
@override
final String template;
@override
final bool isPaused;
@override
final ScheduleParameters parameters;
@override
final bool isChanged;
@override
final int createdAt;
@override
final int updatedAt;
@override
final int archivedAt;
@override
final bool isDeleted;
@override
final String createdUserId;
@override
final String assignedUserId;
@override
final String id;
factory _$ScheduleEntity([void Function(ScheduleEntityBuilder) updates]) =>
(new ScheduleEntityBuilder()..update(updates)).build();
_$ScheduleEntity._(
{this.name,
this.frequencyId,
this.nextRun,
this.template,
this.isPaused,
this.parameters,
this.isChanged,
this.createdAt,
this.updatedAt,
this.archivedAt,
this.isDeleted,
this.createdUserId,
this.assignedUserId,
this.id})
: super._() {
BuiltValueNullFieldError.checkNotNull(name, 'ScheduleEntity', 'name');
BuiltValueNullFieldError.checkNotNull(
frequencyId, 'ScheduleEntity', 'frequencyId');
BuiltValueNullFieldError.checkNotNull(nextRun, 'ScheduleEntity', 'nextRun');
BuiltValueNullFieldError.checkNotNull(
template, 'ScheduleEntity', 'template');
BuiltValueNullFieldError.checkNotNull(
isPaused, 'ScheduleEntity', 'isPaused');
BuiltValueNullFieldError.checkNotNull(
parameters, 'ScheduleEntity', 'parameters');
BuiltValueNullFieldError.checkNotNull(
createdAt, 'ScheduleEntity', 'createdAt');
BuiltValueNullFieldError.checkNotNull(
updatedAt, 'ScheduleEntity', 'updatedAt');
BuiltValueNullFieldError.checkNotNull(
archivedAt, 'ScheduleEntity', 'archivedAt');
BuiltValueNullFieldError.checkNotNull(id, 'ScheduleEntity', 'id');
}
@override
ScheduleEntity rebuild(void Function(ScheduleEntityBuilder) updates) =>
(toBuilder()..update(updates)).build();
@override
ScheduleEntityBuilder toBuilder() =>
new ScheduleEntityBuilder()..replace(this);
@override
bool operator ==(Object other) {
if (identical(other, this)) return true;
return other is ScheduleEntity &&
name == other.name &&
frequencyId == other.frequencyId &&
nextRun == other.nextRun &&
template == other.template &&
isPaused == other.isPaused &&
parameters == other.parameters &&
isChanged == other.isChanged &&
createdAt == other.createdAt &&
updatedAt == other.updatedAt &&
archivedAt == other.archivedAt &&
isDeleted == other.isDeleted &&
createdUserId == other.createdUserId &&
assignedUserId == other.assignedUserId &&
id == other.id;
}
int __hashCode;
@override
int get hashCode {
return __hashCode ??= $jf($jc(
$jc(
$jc(
$jc(
$jc(
$jc(
$jc(
$jc(
$jc(
$jc(
$jc(
$jc(
$jc($jc(0, name.hashCode),
frequencyId.hashCode),
nextRun.hashCode),
template.hashCode),
isPaused.hashCode),
parameters.hashCode),
isChanged.hashCode),
createdAt.hashCode),
updatedAt.hashCode),
archivedAt.hashCode),
isDeleted.hashCode),
createdUserId.hashCode),
assignedUserId.hashCode),
id.hashCode));
}
@override
String toString() {
return (newBuiltValueToStringHelper('ScheduleEntity')
..add('name', name)
..add('frequencyId', frequencyId)
..add('nextRun', nextRun)
..add('template', template)
..add('isPaused', isPaused)
..add('parameters', parameters)
..add('isChanged', isChanged)
..add('createdAt', createdAt)
..add('updatedAt', updatedAt)
..add('archivedAt', archivedAt)
..add('isDeleted', isDeleted)
..add('createdUserId', createdUserId)
..add('assignedUserId', assignedUserId)
..add('id', id))
.toString();
}
}
class ScheduleEntityBuilder
implements Builder<ScheduleEntity, ScheduleEntityBuilder> {
_$ScheduleEntity _$v;
String _name;
String get name => _$this._name;
set name(String name) => _$this._name = name;
String _frequencyId;
String get frequencyId => _$this._frequencyId;
set frequencyId(String frequencyId) => _$this._frequencyId = frequencyId;
String _nextRun;
String get nextRun => _$this._nextRun;
set nextRun(String nextRun) => _$this._nextRun = nextRun;
String _template;
String get template => _$this._template;
set template(String template) => _$this._template = template;
bool _isPaused;
bool get isPaused => _$this._isPaused;
set isPaused(bool isPaused) => _$this._isPaused = isPaused;
ScheduleParametersBuilder _parameters;
ScheduleParametersBuilder get parameters =>
_$this._parameters ??= new ScheduleParametersBuilder();
set parameters(ScheduleParametersBuilder parameters) =>
_$this._parameters = parameters;
bool _isChanged;
bool get isChanged => _$this._isChanged;
set isChanged(bool isChanged) => _$this._isChanged = isChanged;
int _createdAt;
int get createdAt => _$this._createdAt;
set createdAt(int createdAt) => _$this._createdAt = createdAt;
int _updatedAt;
int get updatedAt => _$this._updatedAt;
set updatedAt(int updatedAt) => _$this._updatedAt = updatedAt;
int _archivedAt;
int get archivedAt => _$this._archivedAt;
set archivedAt(int archivedAt) => _$this._archivedAt = archivedAt;
bool _isDeleted;
bool get isDeleted => _$this._isDeleted;
set isDeleted(bool isDeleted) => _$this._isDeleted = isDeleted;
String _createdUserId;
String get createdUserId => _$this._createdUserId;
set createdUserId(String createdUserId) =>
_$this._createdUserId = createdUserId;
String _assignedUserId;
String get assignedUserId => _$this._assignedUserId;
set assignedUserId(String assignedUserId) =>
_$this._assignedUserId = assignedUserId;
String _id;
String get id => _$this._id;
set id(String id) => _$this._id = id;
ScheduleEntityBuilder();
ScheduleEntityBuilder get _$this {
final $v = _$v;
if ($v != null) {
_name = $v.name;
_frequencyId = $v.frequencyId;
_nextRun = $v.nextRun;
_template = $v.template;
_isPaused = $v.isPaused;
_parameters = $v.parameters.toBuilder();
_isChanged = $v.isChanged;
_createdAt = $v.createdAt;
_updatedAt = $v.updatedAt;
_archivedAt = $v.archivedAt;
_isDeleted = $v.isDeleted;
_createdUserId = $v.createdUserId;
_assignedUserId = $v.assignedUserId;
_id = $v.id;
_$v = null;
}
return this;
}
@override
void replace(ScheduleEntity other) {
ArgumentError.checkNotNull(other, 'other');
_$v = other as _$ScheduleEntity;
}
@override
void update(void Function(ScheduleEntityBuilder) updates) {
if (updates != null) updates(this);
}
@override
_$ScheduleEntity build() {
_$ScheduleEntity _$result;
try {
_$result = _$v ??
new _$ScheduleEntity._(
name: BuiltValueNullFieldError.checkNotNull(
name, 'ScheduleEntity', 'name'),
frequencyId: BuiltValueNullFieldError.checkNotNull(
frequencyId, 'ScheduleEntity', 'frequencyId'),
nextRun: BuiltValueNullFieldError.checkNotNull(
nextRun, 'ScheduleEntity', 'nextRun'),
template: BuiltValueNullFieldError.checkNotNull(
template, 'ScheduleEntity', 'template'),
isPaused: BuiltValueNullFieldError.checkNotNull(
isPaused, 'ScheduleEntity', 'isPaused'),
parameters: parameters.build(),
isChanged: isChanged,
createdAt: BuiltValueNullFieldError.checkNotNull(
createdAt, 'ScheduleEntity', 'createdAt'),
updatedAt: BuiltValueNullFieldError.checkNotNull(
updatedAt, 'ScheduleEntity', 'updatedAt'),
archivedAt: BuiltValueNullFieldError.checkNotNull(
archivedAt, 'ScheduleEntity', 'archivedAt'),
isDeleted: isDeleted,
createdUserId: createdUserId,
assignedUserId: assignedUserId,
id: BuiltValueNullFieldError.checkNotNull(id, 'ScheduleEntity', 'id'));
} catch (_) {
String _$failedField;
try {
_$failedField = 'parameters';
parameters.build();
} catch (e) {
throw new BuiltValueNestedFieldError(
'ScheduleEntity', _$failedField, e.toString());
}
rethrow;
}
replace(_$result);
return _$result;
}
}
class _$ScheduleParameters extends ScheduleParameters {
@override
final String dateRange;
@override
final bool showPaymentsTable;
@override
final bool showAgingTable;
@override
final String status;
@override
final BuiltList<String> clients;
factory _$ScheduleParameters(
[void Function(ScheduleParametersBuilder) updates]) =>
(new ScheduleParametersBuilder()..update(updates)).build();
_$ScheduleParameters._(
{this.dateRange,
this.showPaymentsTable,
this.showAgingTable,
this.status,
this.clients})
: super._() {
BuiltValueNullFieldError.checkNotNull(
dateRange, 'ScheduleParameters', 'dateRange');
BuiltValueNullFieldError.checkNotNull(
showPaymentsTable, 'ScheduleParameters', 'showPaymentsTable');
BuiltValueNullFieldError.checkNotNull(
showAgingTable, 'ScheduleParameters', 'showAgingTable');
BuiltValueNullFieldError.checkNotNull(
status, 'ScheduleParameters', 'status');
BuiltValueNullFieldError.checkNotNull(
clients, 'ScheduleParameters', 'clients');
}
@override
ScheduleParameters rebuild(
void Function(ScheduleParametersBuilder) updates) =>
(toBuilder()..update(updates)).build();
@override
ScheduleParametersBuilder toBuilder() =>
new ScheduleParametersBuilder()..replace(this);
@override
bool operator ==(Object other) {
if (identical(other, this)) return true;
return other is ScheduleParameters &&
dateRange == other.dateRange &&
showPaymentsTable == other.showPaymentsTable &&
showAgingTable == other.showAgingTable &&
status == other.status &&
clients == other.clients;
}
int __hashCode;
@override
int get hashCode {
return __hashCode ??= $jf($jc(
$jc(
$jc($jc($jc(0, dateRange.hashCode), showPaymentsTable.hashCode),
showAgingTable.hashCode),
status.hashCode),
clients.hashCode));
}
@override
String toString() {
return (newBuiltValueToStringHelper('ScheduleParameters')
..add('dateRange', dateRange)
..add('showPaymentsTable', showPaymentsTable)
..add('showAgingTable', showAgingTable)
..add('status', status)
..add('clients', clients))
.toString();
}
}
class ScheduleParametersBuilder
implements Builder<ScheduleParameters, ScheduleParametersBuilder> {
_$ScheduleParameters _$v;
String _dateRange;
String get dateRange => _$this._dateRange;
set dateRange(String dateRange) => _$this._dateRange = dateRange;
bool _showPaymentsTable;
bool get showPaymentsTable => _$this._showPaymentsTable;
set showPaymentsTable(bool showPaymentsTable) =>
_$this._showPaymentsTable = showPaymentsTable;
bool _showAgingTable;
bool get showAgingTable => _$this._showAgingTable;
set showAgingTable(bool showAgingTable) =>
_$this._showAgingTable = showAgingTable;
String _status;
String get status => _$this._status;
set status(String status) => _$this._status = status;
ListBuilder<String> _clients;
ListBuilder<String> get clients =>
_$this._clients ??= new ListBuilder<String>();
set clients(ListBuilder<String> clients) => _$this._clients = clients;
ScheduleParametersBuilder();
ScheduleParametersBuilder get _$this {
final $v = _$v;
if ($v != null) {
_dateRange = $v.dateRange;
_showPaymentsTable = $v.showPaymentsTable;
_showAgingTable = $v.showAgingTable;
_status = $v.status;
_clients = $v.clients.toBuilder();
_$v = null;
}
return this;
}
@override
void replace(ScheduleParameters other) {
ArgumentError.checkNotNull(other, 'other');
_$v = other as _$ScheduleParameters;
}
@override
void update(void Function(ScheduleParametersBuilder) updates) {
if (updates != null) updates(this);
}
@override
_$ScheduleParameters build() {
_$ScheduleParameters _$result;
try {
_$result = _$v ??
new _$ScheduleParameters._(
dateRange: BuiltValueNullFieldError.checkNotNull(
dateRange, 'ScheduleParameters', 'dateRange'),
showPaymentsTable: BuiltValueNullFieldError.checkNotNull(
showPaymentsTable, 'ScheduleParameters', 'showPaymentsTable'),
showAgingTable: BuiltValueNullFieldError.checkNotNull(
showAgingTable, 'ScheduleParameters', 'showAgingTable'),
status: BuiltValueNullFieldError.checkNotNull(
status, 'ScheduleParameters', 'status'),
clients: clients.build());
} catch (_) {
String _$failedField;
try {
_$failedField = 'clients';
clients.build();
} catch (e) {
throw new BuiltValueNestedFieldError(
'ScheduleParameters', _$failedField, e.toString());
}
rethrow;
}
replace(_$result);
return _$result;
}
}
// ignore_for_file: always_put_control_body_on_new_line,always_specify_types,annotate_overrides,avoid_annotating_with_dynamic,avoid_as,avoid_catches_without_on_clauses,avoid_returning_this,deprecated_member_use_from_same_package,lines_longer_than_80_chars,omit_local_variable_types,prefer_expression_function_bodies,sort_constructors_first,test_types_in_equals,unnecessary_const,unnecessary_new

View File

@ -52,6 +52,8 @@ import 'package:invoiceninja_flutter/redux/webhook/webhook_state.dart';
import 'package:invoiceninja_flutter/redux/transaction/transaction_state.dart';
import 'package:invoiceninja_flutter/redux/bank_account/bank_account_state.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/redux/schedule/schedule_state.dart';
import 'package:invoiceninja_flutter/redux/transaction_rule/transaction_rule_state.dart';
part 'serializers.g.dart';
@ -117,6 +119,10 @@ part 'serializers.g.dart';
TaxRateItemResponse,
TaxRateListResponse,
// STARTER: serializers - do not remove comment
ScheduleEntity,
ScheduleListResponse,
ScheduleItemResponse,
TransactionRuleEntity,
TransactionRuleListResponse,
TransactionRuleItemResponse,

View File

@ -156,6 +156,12 @@ Serializers _$serializers = (new Serializers().toBuilder()
..add(RegistrationFieldEntity.serializer)
..add(ReportSettingsEntity.serializer)
..add(ReportsUIState.serializer)
..add(ScheduleEntity.serializer)
..add(ScheduleItemResponse.serializer)
..add(ScheduleListResponse.serializer)
..add(ScheduleParameters.serializer)
..add(ScheduleState.serializer)
..add(ScheduleUIState.serializer)
..add(SettingsEntity.serializer)
..add(SettingsUIState.serializer)
..add(SizeEntity.serializer)
@ -458,6 +464,9 @@ Serializers _$serializers = (new Serializers().toBuilder()
..addBuilderFactory(
const FullType(BuiltList, const [const FullType(DocumentEntity)]),
() => new ListBuilder<DocumentEntity>())
..addBuilderFactory(
const FullType(BuiltList, const [const FullType(ScheduleEntity)]),
() => new ListBuilder<ScheduleEntity>())
..addBuilderFactory(
const FullType(BuiltList, const [const FullType(TokenEntity)]),
() => new ListBuilder<TokenEntity>())
@ -536,6 +545,9 @@ Serializers _$serializers = (new Serializers().toBuilder()
..addBuilderFactory(
const FullType(BuiltList, const [const FullType(ProjectEntity)]),
() => new ListBuilder<ProjectEntity>())
..addBuilderFactory(
const FullType(BuiltList, const [const FullType(ScheduleEntity)]),
() => new ListBuilder<ScheduleEntity>())
..addBuilderFactory(
const FullType(BuiltList, const [const FullType(SizeEntity)]),
() => new ListBuilder<SizeEntity>())
@ -548,6 +560,9 @@ Serializers _$serializers = (new Serializers().toBuilder()
..addBuilderFactory(
const FullType(BuiltList, const [const FullType(String)]),
() => new ListBuilder<String>())
..addBuilderFactory(
const FullType(BuiltList, const [const FullType(String)]),
() => new ListBuilder<String>())
..addBuilderFactory(
const FullType(BuiltList, const [
const FullType(BuiltList, const [const FullType(String)])
@ -865,6 +880,13 @@ 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(ScheduleEntity)]),
() => new MapBuilder<String, ScheduleEntity>())
..addBuilderFactory(
const FullType(BuiltList, const [const FullType(String)]),
() => new ListBuilder<String>())
..addBuilderFactory(
const FullType(
BuiltMap, const [const FullType(String), const FullType(String)]),

View File

@ -121,7 +121,7 @@ abstract class SettingsEntity
static const AUTO_BILL_OPT_IN = 'optin';
static const AUTO_BILL_OPT_OUT = 'optout';
static const AUTO_BILL_OFF = 'off';
static const AUTO_BILL_ON_SEND_DATE = 'on_send_date';
static const AUTO_BILL_ON_DUE_DATE = 'on_due_date';

View File

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

View File

@ -58,6 +58,7 @@ import 'package:invoiceninja_flutter/redux/bank_account/bank_account_middleware.
import 'package:invoiceninja_flutter/redux/purchase_order/purchase_order_middleware.dart';
import 'package:invoiceninja_flutter/redux/transaction_rule/transaction_rule_middleware.dart';
import 'package:window_manager/window_manager.dart';
import 'package:invoiceninja_flutter/redux/schedule/schedule_middleware.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/utils/web_stub.dart'
@ -143,6 +144,7 @@ void main({bool isTesting = false}) async {
..addAll(createStoreSettingsMiddleware())
..addAll(createStoreReportsMiddleware())
// STARTER: middleware - do not remove comment
..addAll(createStoreSchedulesMiddleware())
..addAll(createStoreTransactionRulesMiddleware())
..addAll(createStoreTransactionsMiddleware())
..addAll(createStoreBankAccountsMiddleware())

View File

@ -98,6 +98,11 @@ import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/utils/platforms.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/ui/schedule/schedule_screen.dart';
import 'package:invoiceninja_flutter/ui/schedule/edit/schedule_edit_vm.dart';
import 'package:invoiceninja_flutter/ui/schedule/view/schedule_view_vm.dart';
import 'package:invoiceninja_flutter/ui/schedule/schedule_screen_vm.dart';
import 'package:invoiceninja_flutter/ui/transaction_rule/transaction_rule_screen.dart';
import 'package:invoiceninja_flutter/ui/transaction_rule/edit/transaction_rule_edit_vm.dart';
import 'package:invoiceninja_flutter/ui/transaction_rule/view/transaction_rule_view_vm.dart';
@ -533,6 +538,13 @@ class InvoiceNinjaAppState extends State<InvoiceNinjaApp> {
QuoteEmailScreen(),
QuotePdfScreen.route: (context) => QuotePdfScreen(),
// STARTER: routes - do not remove comment
ScheduleScreen.route: (context) =>
ScheduleScreenBuilder(),
ScheduleViewScreen.route: (context) =>
ScheduleViewScreen(),
ScheduleEditScreen.route: (context) =>
ScheduleEditScreen(),
TransactionRuleScreen.route: (context) =>
TransactionRuleScreenBuilder(),
TransactionRuleViewScreen.route: (context) =>

View File

@ -65,6 +65,8 @@ import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/utils/platforms.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/redux/schedule/schedule_actions.dart';
import 'package:invoiceninja_flutter/redux/transaction_rule/transaction_rule_actions.dart';
import 'package:invoiceninja_flutter/redux/transaction/transaction_actions.dart';
@ -392,6 +394,10 @@ void viewEntitiesByType({
action = ViewGroupList();
break;
// STARTER: view list - do not remove comment
case EntityType.schedule:
action = ViewScheduleList();
break;
case EntityType.transactionRule:
action = ViewTransactionRuleList();
break;
@ -618,6 +624,13 @@ void viewEntityById({
));
break;
// STARTER: view - do not remove comment
case EntityType.schedule:
store.dispatch(ViewSchedule(
scheduleId: entityId,
force: force,
));
break;
case EntityType.transactionRule:
store.dispatch(ViewTransactionRule(
transactionRuleId: entityId,
@ -871,6 +884,13 @@ void createEntityByType({
));
break;
// STARTER: create type - do not remove comment
case EntityType.schedule:
store.dispatch(EditSchedule(
force: force,
schedule: ScheduleEntity(state: state),
));
break;
case EntityType.transactionRule:
store.dispatch(EditTransactionRule(
force: force,
@ -1108,6 +1128,14 @@ void createEntity({
));
break;
// STARTER: create - do not remove comment
case EntityType.schedule:
store.dispatch(EditSchedule(
schedule: entity,
force: force,
completer: completer,
));
break;
case EntityType.transactionRule:
store.dispatch(EditTransactionRule(
transactionRule: entity,
@ -1329,6 +1357,11 @@ void editEntity({
));
break;
// STARTER: edit - do not remove comment
case EntityType.schedule:
store
.dispatch(EditSchedule(schedule: entity, completer: completer));
break;
case EntityType.transactionRule:
store.dispatch(EditTransactionRule(
transactionRule: entity, completer: completer));
@ -1522,6 +1555,10 @@ void handleEntitiesActions(List<BaseEntity> entities, EntityAction action,
handleDocumentAction(context, entities, action);
break;
// STARTER: actions - do not remove comment
case EntityType.schedule:
handleScheduleAction(context, entities, action);
break;
case EntityType.transactionRule:
handleTransactionRuleAction(context, entities, action);
break;

View File

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

View File

@ -72,6 +72,9 @@ import 'package:invoiceninja_flutter/redux/bank_account/bank_account_state.dart'
import 'package:invoiceninja_flutter/redux/purchase_order/purchase_order_state.dart';
import 'package:invoiceninja_flutter/ui/purchase_order/edit/purchase_order_edit_vm.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/redux/schedule/schedule_state.dart';
import 'package:invoiceninja_flutter/ui/schedule/edit/schedule_edit_vm.dart';
import 'package:invoiceninja_flutter/redux/transaction_rule/transaction_rule_state.dart';
import 'package:invoiceninja_flutter/ui/transaction_rule/edit/transaction_rule_edit_vm.dart';
@ -279,6 +282,9 @@ abstract class AppState implements Built<AppState, AppStateBuilder> {
case EntityType.invoice:
return invoiceState.map;
// STARTER: states switch map - do not remove comment
case EntityType.schedule:
return scheduleState.map;
case EntityType.transactionRule:
return transactionRuleState.map;
@ -371,6 +377,9 @@ abstract class AppState implements Built<AppState, AppStateBuilder> {
case EntityType.invoice:
return invoiceState.list;
// STARTER: states switch list - do not remove comment
case EntityType.schedule:
return scheduleState.list;
case EntityType.transactionRule:
return transactionRuleState.list;
@ -452,6 +461,9 @@ abstract class AppState implements Built<AppState, AppStateBuilder> {
case EntityType.invoice:
return invoiceUIState;
// STARTER: states switch - do not remove comment
case EntityType.schedule:
return scheduleUIState;
case EntityType.transactionRule:
return transactionRuleUIState;
@ -534,6 +546,10 @@ abstract class AppState implements Built<AppState, AppStateBuilder> {
ListUIState get invoiceListState => uiState.invoiceUIState.listUIState;
// STARTER: state getters - do not remove comment
ScheduleState get scheduleState => userCompanyState.scheduleState;
ListUIState get scheduleListState => uiState.scheduleUIState.listUIState;
ScheduleUIState get scheduleUIState => uiState.scheduleUIState;
TransactionRuleState get transactionRuleState =>
userCompanyState.transactionRuleState;
ListUIState get transactionRuleListState =>
@ -726,6 +742,9 @@ abstract class AppState implements Built<AppState, AppStateBuilder> {
case CreditEditScreen.route:
return creditUIState.editing.isChanged == true;
// STARTER: has changes - do not remove comment
case ScheduleEditScreen.route:
return scheduleUIState.editing.isChanged == true;
case TransactionRuleEditScreen.route:
return transactionRuleUIState.editing.isChanged == true;
case TransactionEditScreen.route:

View File

@ -36,6 +36,8 @@ import 'package:invoiceninja_flutter/redux/vendor/vendor_reducer.dart';
import 'package:invoiceninja_flutter/redux/webhook/webhook_reducer.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/redux/schedule/schedule_reducer.dart';
import 'package:invoiceninja_flutter/redux/transaction_rule/transaction_rule_reducer.dart';
import 'package:invoiceninja_flutter/redux/transaction/transaction_reducer.dart';
@ -60,6 +62,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
..scheduleState.replace(schedulesReducer(state.scheduleState, action))
..transactionRuleState
.replace(transactionRulesReducer(state.transactionRuleState, action))
..transactionState

View File

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

View File

@ -53,6 +53,9 @@ class _$UserCompanyStateSerializer
'quoteState',
serializers.serialize(object.quoteState,
specifiedType: const FullType(QuoteState)),
'scheduleState',
serializers.serialize(object.scheduleState,
specifiedType: const FullType(ScheduleState)),
'transactionRuleState',
serializers.serialize(object.transactionRuleState,
specifiedType: const FullType(TransactionRuleState)),
@ -180,6 +183,10 @@ class _$UserCompanyStateSerializer
result.quoteState.replace(serializers.deserialize(value,
specifiedType: const FullType(QuoteState)) as QuoteState);
break;
case 'scheduleState':
result.scheduleState.replace(serializers.deserialize(value,
specifiedType: const FullType(ScheduleState)) as ScheduleState);
break;
case 'transactionRuleState':
result.transactionRuleState.replace(serializers.deserialize(value,
specifiedType: const FullType(TransactionRuleState))
@ -296,6 +303,8 @@ class _$UserCompanyState extends UserCompanyState {
@override
final QuoteState quoteState;
@override
final ScheduleState scheduleState;
@override
final TransactionRuleState transactionRuleState;
@override
final TransactionState transactionState;
@ -349,6 +358,7 @@ class _$UserCompanyState extends UserCompanyState {
this.projectState,
this.paymentState,
this.quoteState,
this.scheduleState,
this.transactionRuleState,
this.transactionState,
this.bankAccountState,
@ -390,6 +400,8 @@ class _$UserCompanyState extends UserCompanyState {
paymentState, 'UserCompanyState', 'paymentState');
BuiltValueNullFieldError.checkNotNull(
quoteState, 'UserCompanyState', 'quoteState');
BuiltValueNullFieldError.checkNotNull(
scheduleState, 'UserCompanyState', 'scheduleState');
BuiltValueNullFieldError.checkNotNull(
transactionRuleState, 'UserCompanyState', 'transactionRuleState');
BuiltValueNullFieldError.checkNotNull(
@ -452,6 +464,7 @@ class _$UserCompanyState extends UserCompanyState {
projectState == other.projectState &&
paymentState == other.paymentState &&
quoteState == other.quoteState &&
scheduleState == other.scheduleState &&
transactionRuleState == other.transactionRuleState &&
transactionState == other.transactionState &&
bankAccountState == other.bankAccountState &&
@ -493,8 +506,8 @@ class _$UserCompanyState extends UserCompanyState {
$jc(
$jc(
$jc(
$jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc(0, lastUpdated.hashCode), userCompany.hashCode), documentState.hashCode), productState.hashCode), clientState.hashCode), invoiceState.hashCode), expenseState.hashCode), vendorState.hashCode), taskState.hashCode), projectState.hashCode), paymentState.hashCode),
quoteState.hashCode),
$jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc(0, lastUpdated.hashCode), userCompany.hashCode), documentState.hashCode), productState.hashCode), clientState.hashCode), invoiceState.hashCode), expenseState.hashCode), vendorState.hashCode), taskState.hashCode), projectState.hashCode), paymentState.hashCode), quoteState.hashCode),
scheduleState.hashCode),
transactionRuleState.hashCode),
transactionState.hashCode),
bankAccountState.hashCode),
@ -530,6 +543,7 @@ class _$UserCompanyState extends UserCompanyState {
..add('projectState', projectState)
..add('paymentState', paymentState)
..add('quoteState', quoteState)
..add('scheduleState', scheduleState)
..add('transactionRuleState', transactionRuleState)
..add('transactionState', transactionState)
..add('bankAccountState', bankAccountState)
@ -625,6 +639,12 @@ class UserCompanyStateBuilder
set quoteState(QuoteStateBuilder quoteState) =>
_$this._quoteState = quoteState;
ScheduleStateBuilder _scheduleState;
ScheduleStateBuilder get scheduleState =>
_$this._scheduleState ??= new ScheduleStateBuilder();
set scheduleState(ScheduleStateBuilder scheduleState) =>
_$this._scheduleState = scheduleState;
TransactionRuleStateBuilder _transactionRuleState;
TransactionRuleStateBuilder get transactionRuleState =>
_$this._transactionRuleState ??= new TransactionRuleStateBuilder();
@ -751,6 +771,7 @@ class UserCompanyStateBuilder
_projectState = $v.projectState.toBuilder();
_paymentState = $v.paymentState.toBuilder();
_quoteState = $v.quoteState.toBuilder();
_scheduleState = $v.scheduleState.toBuilder();
_transactionRuleState = $v.transactionRuleState.toBuilder();
_transactionState = $v.transactionState.toBuilder();
_bankAccountState = $v.bankAccountState.toBuilder();
@ -804,6 +825,7 @@ class UserCompanyStateBuilder
projectState: projectState.build(),
paymentState: paymentState.build(),
quoteState: quoteState.build(),
scheduleState: scheduleState.build(),
transactionRuleState: transactionRuleState.build(),
transactionState: transactionState.build(),
bankAccountState: bankAccountState.build(),
@ -847,6 +869,8 @@ class UserCompanyStateBuilder
paymentState.build();
_$failedField = 'quoteState';
quoteState.build();
_$failedField = 'scheduleState';
scheduleState.build();
_$failedField = 'transactionRuleState';
transactionRuleState.build();
_$failedField = 'transactionState';

View File

@ -271,7 +271,6 @@ class FilterPaymentsByStatus implements PersistUI {
final EntityStatus status;
}
class FilterPaymentsByCustom1 implements PersistUI {
FilterPaymentsByCustom1(this.value);

View File

@ -0,0 +1,321 @@
import 'dart:async';
import 'package:built_collection/built_collection.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/ui/app/entities/entity_actions_dialog.dart';
class ViewScheduleList implements PersistUI {
ViewScheduleList({this.force = false});
final bool force;
}
class ViewSchedule implements PersistUI, PersistPrefs {
ViewSchedule({
@required this.scheduleId,
this.force = false,
});
final String scheduleId;
final bool force;
}
class EditSchedule implements PersistUI, PersistPrefs {
EditSchedule(
{@required this.schedule,
this.completer,
this.cancelCompleter,
this.force = false});
final ScheduleEntity schedule;
final Completer completer;
final Completer cancelCompleter;
final bool force;
}
class UpdateSchedule implements PersistUI {
UpdateSchedule(this.schedule);
final ScheduleEntity schedule;
}
class LoadSchedule {
LoadSchedule({this.completer, this.scheduleId});
final Completer completer;
final String scheduleId;
}
class LoadScheduleActivity {
LoadScheduleActivity({this.completer, this.scheduleId});
final Completer completer;
final String scheduleId;
}
class LoadSchedules {
LoadSchedules({this.completer});
final Completer completer;
}
class LoadScheduleRequest implements StartLoading {}
class LoadScheduleFailure implements StopLoading {
LoadScheduleFailure(this.error);
final dynamic error;
@override
String toString() {
return 'LoadScheduleFailure{error: $error}';
}
}
class LoadScheduleSuccess implements StopLoading, PersistData {
LoadScheduleSuccess(this.schedule);
final ScheduleEntity schedule;
@override
String toString() {
return 'LoadScheduleSuccess{schedule: $schedule}';
}
}
class LoadSchedulesRequest implements StartLoading {}
class LoadSchedulesFailure implements StopLoading {
LoadSchedulesFailure(this.error);
final dynamic error;
@override
String toString() {
return 'LoadSchedulesFailure{error: $error}';
}
}
class LoadSchedulesSuccess implements StopLoading {
LoadSchedulesSuccess(this.schedules);
final BuiltList<ScheduleEntity> schedules;
@override
String toString() {
return 'LoadSchedulesSuccess{schedules: $schedules}';
}
}
class SaveScheduleRequest implements StartSaving {
SaveScheduleRequest({this.completer, this.schedule});
final Completer completer;
final ScheduleEntity schedule;
}
class SaveScheduleSuccess implements StopSaving, PersistData, PersistUI {
SaveScheduleSuccess(this.schedule);
final ScheduleEntity schedule;
}
class AddScheduleSuccess implements StopSaving, PersistData, PersistUI {
AddScheduleSuccess(this.schedule);
final ScheduleEntity schedule;
}
class SaveScheduleFailure implements StopSaving {
SaveScheduleFailure(this.error);
final Object error;
}
class ArchiveSchedulesRequest implements StartSaving {
ArchiveSchedulesRequest(this.completer, this.scheduleIds);
final Completer completer;
final List<String> scheduleIds;
}
class ArchiveSchedulesSuccess implements StopSaving, PersistData {
ArchiveSchedulesSuccess(this.schedules);
final List<ScheduleEntity> schedules;
}
class ArchiveSchedulesFailure implements StopSaving {
ArchiveSchedulesFailure(this.schedules);
final List<ScheduleEntity> schedules;
}
class DeleteSchedulesRequest implements StartSaving {
DeleteSchedulesRequest(this.completer, this.scheduleIds);
final Completer completer;
final List<String> scheduleIds;
}
class DeleteSchedulesSuccess implements StopSaving, PersistData {
DeleteSchedulesSuccess(this.schedules);
final List<ScheduleEntity> schedules;
}
class DeleteSchedulesFailure implements StopSaving {
DeleteSchedulesFailure(this.schedules);
final List<ScheduleEntity> schedules;
}
class RestoreSchedulesRequest implements StartSaving {
RestoreSchedulesRequest(this.completer, this.scheduleIds);
final Completer completer;
final List<String> scheduleIds;
}
class RestoreSchedulesSuccess implements StopSaving, PersistData {
RestoreSchedulesSuccess(this.schedules);
final List<ScheduleEntity> schedules;
}
class RestoreSchedulesFailure implements StopSaving {
RestoreSchedulesFailure(this.schedules);
final List<ScheduleEntity> schedules;
}
class FilterSchedules implements PersistUI {
FilterSchedules(this.filter);
final String filter;
}
class SortSchedules implements PersistUI, PersistPrefs {
SortSchedules(this.field);
final String field;
}
class FilterSchedulesByState implements PersistUI {
FilterSchedulesByState(this.state);
final EntityState state;
}
class FilterSchedulesByCustom1 implements PersistUI {
FilterSchedulesByCustom1(this.value);
final String value;
}
class FilterSchedulesByCustom2 implements PersistUI {
FilterSchedulesByCustom2(this.value);
final String value;
}
class FilterSchedulesByCustom3 implements PersistUI {
FilterSchedulesByCustom3(this.value);
final String value;
}
class FilterSchedulesByCustom4 implements PersistUI {
FilterSchedulesByCustom4(this.value);
final String value;
}
class StartScheduleMultiselect {
StartScheduleMultiselect();
}
class AddToScheduleMultiselect {
AddToScheduleMultiselect({@required this.entity});
final BaseEntity entity;
}
class RemoveFromScheduleMultiselect {
RemoveFromScheduleMultiselect({@required this.entity});
final BaseEntity entity;
}
class ClearScheduleMultiselect {
ClearScheduleMultiselect();
}
class UpdateScheduleTab implements PersistUI {
UpdateScheduleTab({this.tabIndex});
final int tabIndex;
}
void handleScheduleAction(
BuildContext context, List<BaseEntity> schedules, EntityAction action) {
if (schedules.isEmpty) {
return;
}
final store = StoreProvider.of<AppState>(context);
final localization = AppLocalization.of(context);
final schedule = schedules.first as ScheduleEntity;
final scheduleIds = schedules.map((schedule) => schedule.id).toList();
switch (action) {
case EntityAction.edit:
editEntity(entity: schedule);
break;
case EntityAction.restore:
store.dispatch(RestoreSchedulesRequest(
snackBarCompleter<Null>(context, localization.restoredSchedule),
scheduleIds));
break;
case EntityAction.archive:
store.dispatch(ArchiveSchedulesRequest(
snackBarCompleter<Null>(context, localization.archivedSchedule),
scheduleIds));
break;
case EntityAction.delete:
store.dispatch(DeleteSchedulesRequest(
snackBarCompleter<Null>(context, localization.deletedSchedule),
scheduleIds));
break;
case EntityAction.toggleMultiselect:
if (!store.state.scheduleListState.isInMultiselect()) {
store.dispatch(StartScheduleMultiselect());
}
if (schedules.isEmpty) {
break;
}
for (final schedule in schedules) {
if (!store.state.scheduleListState.isSelected(schedule.id)) {
store.dispatch(AddToScheduleMultiselect(entity: schedule));
} else {
store.dispatch(RemoveFromScheduleMultiselect(entity: schedule));
}
}
break;
case EntityAction.more:
showEntityActionsDialog(
entities: [schedule],
);
break;
default:
print('## ERROR: unhandled action $action in schedule_actions');
break;
}
}

View File

@ -0,0 +1,236 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:redux/redux.dart';
import 'package:invoiceninja_flutter/main_app.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/ui/ui_actions.dart';
import 'package:invoiceninja_flutter/ui/schedule/schedule_screen.dart';
import 'package:invoiceninja_flutter/ui/schedule/edit/schedule_edit_vm.dart';
import 'package:invoiceninja_flutter/ui/schedule/view/schedule_view_vm.dart';
import 'package:invoiceninja_flutter/redux/schedule/schedule_actions.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/data/repositories/schedule_repository.dart';
List<Middleware<AppState>> createStoreSchedulesMiddleware([
ScheduleRepository repository = const ScheduleRepository(),
]) {
final viewScheduleList = _viewScheduleList();
final viewSchedule = _viewSchedule();
final editSchedule = _editSchedule();
final loadSchedules = _loadSchedules(repository);
final loadSchedule = _loadSchedule(repository);
final saveSchedule = _saveSchedule(repository);
final archiveSchedule = _archiveSchedule(repository);
final deleteSchedule = _deleteSchedule(repository);
final restoreSchedule = _restoreSchedule(repository);
return [
TypedMiddleware<AppState, ViewScheduleList>(viewScheduleList),
TypedMiddleware<AppState, ViewSchedule>(viewSchedule),
TypedMiddleware<AppState, EditSchedule>(editSchedule),
TypedMiddleware<AppState, LoadSchedules>(loadSchedules),
TypedMiddleware<AppState, LoadSchedule>(loadSchedule),
TypedMiddleware<AppState, SaveScheduleRequest>(saveSchedule),
TypedMiddleware<AppState, ArchiveSchedulesRequest>(archiveSchedule),
TypedMiddleware<AppState, DeleteSchedulesRequest>(deleteSchedule),
TypedMiddleware<AppState, RestoreSchedulesRequest>(restoreSchedule),
];
}
Middleware<AppState> _editSchedule() {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as EditSchedule;
next(action);
store.dispatch(UpdateCurrentRoute(ScheduleEditScreen.route));
if (store.state.prefState.isMobile) {
navigatorKey.currentState.pushNamed(ScheduleEditScreen.route);
}
};
}
Middleware<AppState> _viewSchedule() {
return (Store<AppState> store, dynamic dynamicAction,
NextDispatcher next) async {
final action = dynamicAction as ViewSchedule;
next(action);
store.dispatch(UpdateCurrentRoute(ScheduleViewScreen.route));
if (store.state.prefState.isMobile) {
navigatorKey.currentState.pushNamed(ScheduleViewScreen.route);
}
};
}
Middleware<AppState> _viewScheduleList() {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as ViewScheduleList;
next(action);
if (store.state.staticState.isStale) {
store.dispatch(RefreshData());
}
store.dispatch(UpdateCurrentRoute(ScheduleScreen.route));
if (store.state.prefState.isMobile) {
navigatorKey.currentState.pushNamedAndRemoveUntil(
ScheduleScreen.route, (Route<dynamic> route) => false);
}
};
}
Middleware<AppState> _archiveSchedule(ScheduleRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as ArchiveSchedulesRequest;
final prevSchedules = action.scheduleIds
.map((id) => store.state.scheduleState.map[id])
.toList();
repository
.bulkAction(
store.state.credentials, action.scheduleIds, EntityAction.archive)
.then((List<ScheduleEntity> schedules) {
store.dispatch(ArchiveSchedulesSuccess(schedules));
if (action.completer != null) {
action.completer.complete(null);
}
}).catchError((Object error) {
print(error);
store.dispatch(ArchiveSchedulesFailure(prevSchedules));
if (action.completer != null) {
action.completer.completeError(error);
}
});
next(action);
};
}
Middleware<AppState> _deleteSchedule(ScheduleRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as DeleteSchedulesRequest;
final prevSchedules = action.scheduleIds
.map((id) => store.state.scheduleState.map[id])
.toList();
repository
.bulkAction(
store.state.credentials, action.scheduleIds, EntityAction.delete)
.then((List<ScheduleEntity> schedules) {
store.dispatch(DeleteSchedulesSuccess(schedules));
if (action.completer != null) {
action.completer.complete(null);
}
}).catchError((Object error) {
print(error);
store.dispatch(DeleteSchedulesFailure(prevSchedules));
if (action.completer != null) {
action.completer.completeError(error);
}
});
next(action);
};
}
Middleware<AppState> _restoreSchedule(ScheduleRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as RestoreSchedulesRequest;
final prevSchedules = action.scheduleIds
.map((id) => store.state.scheduleState.map[id])
.toList();
repository
.bulkAction(
store.state.credentials, action.scheduleIds, EntityAction.restore)
.then((List<ScheduleEntity> schedules) {
store.dispatch(RestoreSchedulesSuccess(schedules));
if (action.completer != null) {
action.completer.complete(null);
}
}).catchError((Object error) {
print(error);
store.dispatch(RestoreSchedulesFailure(prevSchedules));
if (action.completer != null) {
action.completer.completeError(error);
}
});
next(action);
};
}
Middleware<AppState> _saveSchedule(ScheduleRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as SaveScheduleRequest;
repository
.saveData(store.state.credentials, action.schedule)
.then((ScheduleEntity schedule) {
if (action.schedule.isNew) {
store.dispatch(AddScheduleSuccess(schedule));
} else {
store.dispatch(SaveScheduleSuccess(schedule));
}
action.completer.complete(schedule);
}).catchError((Object error) {
print(error);
store.dispatch(SaveScheduleFailure(error));
action.completer.completeError(error);
});
next(action);
};
}
Middleware<AppState> _loadSchedule(ScheduleRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as LoadSchedule;
final AppState state = store.state;
store.dispatch(LoadScheduleRequest());
repository.loadItem(state.credentials, action.scheduleId).then((schedule) {
store.dispatch(LoadScheduleSuccess(schedule));
if (action.completer != null) {
action.completer.complete(null);
}
}).catchError((Object error) {
print(error);
store.dispatch(LoadScheduleFailure(error));
if (action.completer != null) {
action.completer.completeError(error);
}
});
next(action);
};
}
Middleware<AppState> _loadSchedules(ScheduleRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as LoadSchedules;
final AppState state = store.state;
store.dispatch(LoadSchedulesRequest());
repository.loadList(state.credentials).then((data) {
store.dispatch(LoadSchedulesSuccess(data));
if (action.completer != null) {
action.completer.complete(null);
}
}).catchError((Object error) {
print(error);
store.dispatch(LoadSchedulesFailure(error));
if (action.completer != null) {
action.completer.completeError(error);
}
});
next(action);
};
}

View File

@ -0,0 +1,256 @@
import 'package:redux/redux.dart';
import 'package:built_collection/built_collection.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/company/company_actions.dart';
import 'package:invoiceninja_flutter/redux/ui/entity_ui_state.dart';
import 'package:invoiceninja_flutter/redux/schedule/schedule_actions.dart';
import 'package:invoiceninja_flutter/redux/ui/list_ui_state.dart';
import 'package:invoiceninja_flutter/redux/schedule/schedule_state.dart';
EntityUIState scheduleUIReducer(ScheduleUIState state, dynamic action) {
return state.rebuild((b) => b
..listUIState.replace(scheduleListReducer(state.listUIState, action))
..editing.replace(editingReducer(state.editing, action))
..selectedId = selectedIdReducer(state.selectedId, action)
..forceSelected = forceSelectedReducer(state.forceSelected, action)
..tabIndex = tabIndexReducer(state.tabIndex, action));
}
final forceSelectedReducer = combineReducers<bool>([
TypedReducer<bool, ViewSchedule>((completer, action) => true),
TypedReducer<bool, ViewScheduleList>((completer, action) => false),
TypedReducer<bool, FilterSchedulesByState>((completer, action) => false),
TypedReducer<bool, FilterSchedules>((completer, action) => false),
TypedReducer<bool, FilterSchedulesByCustom1>((completer, action) => false),
TypedReducer<bool, FilterSchedulesByCustom2>((completer, action) => false),
TypedReducer<bool, FilterSchedulesByCustom3>((completer, action) => false),
TypedReducer<bool, FilterSchedulesByCustom4>((completer, action) => false),
]);
final tabIndexReducer = combineReducers<int>([
TypedReducer<int, UpdateScheduleTab>((completer, action) {
return action.tabIndex;
}),
TypedReducer<int, PreviewEntity>((completer, action) {
return 0;
}),
]);
Reducer<String> selectedIdReducer = combineReducers([
TypedReducer<String, ArchiveSchedulesSuccess>((completer, action) => ''),
TypedReducer<String, DeleteSchedulesSuccess>((completer, action) => ''),
TypedReducer<String, PreviewEntity>((selectedId, action) =>
action.entityType == EntityType.schedule ? action.entityId : selectedId),
TypedReducer<String, ViewSchedule>(
(String selectedId, dynamic action) => action.scheduleId),
TypedReducer<String, AddScheduleSuccess>(
(String selectedId, dynamic action) => action.schedule.id),
TypedReducer<String, SelectCompany>(
(selectedId, action) => action.clearSelection ? '' : selectedId),
TypedReducer<String, ClearEntityFilter>((selectedId, action) => ''),
TypedReducer<String, SortSchedules>((selectedId, action) => ''),
TypedReducer<String, FilterSchedules>((selectedId, action) => ''),
TypedReducer<String, FilterSchedulesByState>((selectedId, action) => ''),
TypedReducer<String, FilterSchedulesByCustom1>((selectedId, action) => ''),
TypedReducer<String, FilterSchedulesByCustom2>((selectedId, action) => ''),
TypedReducer<String, FilterSchedulesByCustom3>((selectedId, action) => ''),
TypedReducer<String, FilterSchedulesByCustom4>((selectedId, action) => ''),
TypedReducer<String, FilterByEntity>(
(selectedId, action) => action.clearSelection
? ''
: action.entityType == EntityType.schedule
? action.entityId
: selectedId),
]);
final editingReducer = combineReducers<ScheduleEntity>([
TypedReducer<ScheduleEntity, SaveScheduleSuccess>(_updateEditing),
TypedReducer<ScheduleEntity, AddScheduleSuccess>(_updateEditing),
TypedReducer<ScheduleEntity, RestoreSchedulesSuccess>((schedules, action) {
return action.schedules[0];
}),
TypedReducer<ScheduleEntity, ArchiveSchedulesSuccess>((schedules, action) {
return action.schedules[0];
}),
TypedReducer<ScheduleEntity, DeleteSchedulesSuccess>((schedules, action) {
return action.schedules[0];
}),
TypedReducer<ScheduleEntity, EditSchedule>(_updateEditing),
TypedReducer<ScheduleEntity, UpdateSchedule>((schedule, action) {
return action.schedule.rebuild((b) => b..isChanged = true);
}),
TypedReducer<ScheduleEntity, DiscardChanges>(_clearEditing),
]);
ScheduleEntity _clearEditing(ScheduleEntity schedule, dynamic action) {
return ScheduleEntity();
}
ScheduleEntity _updateEditing(ScheduleEntity schedule, dynamic action) {
return action.schedule;
}
final scheduleListReducer = combineReducers<ListUIState>([
TypedReducer<ListUIState, SortSchedules>(_sortSchedules),
TypedReducer<ListUIState, FilterSchedulesByState>(_filterSchedulesByState),
TypedReducer<ListUIState, FilterSchedules>(_filterSchedules),
TypedReducer<ListUIState, FilterSchedulesByCustom1>(
_filterSchedulesByCustom1),
TypedReducer<ListUIState, FilterSchedulesByCustom2>(
_filterSchedulesByCustom2),
TypedReducer<ListUIState, StartScheduleMultiselect>(_startListMultiselect),
TypedReducer<ListUIState, AddToScheduleMultiselect>(_addToListMultiselect),
TypedReducer<ListUIState, RemoveFromScheduleMultiselect>(
_removeFromListMultiselect),
TypedReducer<ListUIState, ClearScheduleMultiselect>(_clearListMultiselect),
TypedReducer<ListUIState, ViewScheduleList>(_viewScheduleList),
TypedReducer<ListUIState, FilterByEntity>(
(state, action) => state.rebuild((b) => b
..filter = null
..filterClearedAt = DateTime.now().millisecondsSinceEpoch)),
]);
ListUIState _viewScheduleList(
ListUIState scheduleListState, ViewScheduleList action) {
return scheduleListState.rebuild((b) => b
..selectedIds = null
..filter = null
..filterClearedAt = DateTime.now().millisecondsSinceEpoch);
}
ListUIState _filterSchedulesByCustom1(
ListUIState scheduleListState, FilterSchedulesByCustom1 action) {
if (scheduleListState.custom1Filters.contains(action.value)) {
return scheduleListState
.rebuild((b) => b..custom1Filters.remove(action.value));
} else {
return scheduleListState
.rebuild((b) => b..custom1Filters.add(action.value));
}
}
ListUIState _filterSchedulesByCustom2(
ListUIState scheduleListState, FilterSchedulesByCustom2 action) {
if (scheduleListState.custom2Filters.contains(action.value)) {
return scheduleListState
.rebuild((b) => b..custom2Filters.remove(action.value));
} else {
return scheduleListState
.rebuild((b) => b..custom2Filters.add(action.value));
}
}
ListUIState _filterSchedulesByState(
ListUIState scheduleListState, FilterSchedulesByState action) {
if (scheduleListState.stateFilters.contains(action.state)) {
return scheduleListState
.rebuild((b) => b..stateFilters.remove(action.state));
} else {
return scheduleListState.rebuild((b) => b..stateFilters.add(action.state));
}
}
ListUIState _filterSchedules(
ListUIState scheduleListState, FilterSchedules action) {
return scheduleListState.rebuild((b) => b
..filter = action.filter
..filterClearedAt = action.filter == null
? DateTime.now().millisecondsSinceEpoch
: scheduleListState.filterClearedAt);
}
ListUIState _sortSchedules(
ListUIState scheduleListState, SortSchedules action) {
return scheduleListState.rebuild((b) => b
..sortAscending = b.sortField != action.field || !b.sortAscending
..sortField = action.field);
}
ListUIState _startListMultiselect(
ListUIState productListState, StartScheduleMultiselect action) {
return productListState.rebuild((b) => b..selectedIds = ListBuilder());
}
ListUIState _addToListMultiselect(
ListUIState productListState, AddToScheduleMultiselect action) {
return productListState.rebuild((b) => b..selectedIds.add(action.entity.id));
}
ListUIState _removeFromListMultiselect(
ListUIState productListState, RemoveFromScheduleMultiselect action) {
return productListState
.rebuild((b) => b..selectedIds.remove(action.entity.id));
}
ListUIState _clearListMultiselect(
ListUIState productListState, ClearScheduleMultiselect action) {
return productListState.rebuild((b) => b..selectedIds = null);
}
final schedulesReducer = combineReducers<ScheduleState>([
TypedReducer<ScheduleState, SaveScheduleSuccess>(_updateSchedule),
TypedReducer<ScheduleState, AddScheduleSuccess>(_addSchedule),
TypedReducer<ScheduleState, LoadSchedulesSuccess>(_setLoadedSchedules),
TypedReducer<ScheduleState, LoadScheduleSuccess>(_setLoadedSchedule),
TypedReducer<ScheduleState, LoadCompanySuccess>(_setLoadedCompany),
TypedReducer<ScheduleState, ArchiveSchedulesSuccess>(_archiveScheduleSuccess),
TypedReducer<ScheduleState, DeleteSchedulesSuccess>(_deleteScheduleSuccess),
TypedReducer<ScheduleState, RestoreSchedulesSuccess>(_restoreScheduleSuccess),
]);
ScheduleState _archiveScheduleSuccess(
ScheduleState scheduleState, ArchiveSchedulesSuccess action) {
return scheduleState.rebuild((b) {
for (final schedule in action.schedules) {
b.map[schedule.id] = schedule;
}
});
}
ScheduleState _deleteScheduleSuccess(
ScheduleState scheduleState, DeleteSchedulesSuccess action) {
return scheduleState.rebuild((b) {
for (final schedule in action.schedules) {
b.map[schedule.id] = schedule;
}
});
}
ScheduleState _restoreScheduleSuccess(
ScheduleState scheduleState, RestoreSchedulesSuccess action) {
return scheduleState.rebuild((b) {
for (final schedule in action.schedules) {
b.map[schedule.id] = schedule;
}
});
}
ScheduleState _addSchedule(
ScheduleState scheduleState, AddScheduleSuccess action) {
return scheduleState.rebuild((b) => b
..map[action.schedule.id] = action.schedule
..list.add(action.schedule.id));
}
ScheduleState _updateSchedule(
ScheduleState scheduleState, SaveScheduleSuccess action) {
return scheduleState
.rebuild((b) => b..map[action.schedule.id] = action.schedule);
}
ScheduleState _setLoadedSchedule(
ScheduleState scheduleState, LoadScheduleSuccess action) {
return scheduleState
.rebuild((b) => b..map[action.schedule.id] = action.schedule);
}
ScheduleState _setLoadedSchedules(
ScheduleState scheduleState, LoadSchedulesSuccess action) =>
scheduleState.loadSchedules(action.schedules);
ScheduleState _setLoadedCompany(
ScheduleState scheduleState, LoadCompanySuccess action) {
final company = action.userCompany.company;
return scheduleState.loadSchedules(company.schedules);
}

View File

@ -0,0 +1,78 @@
import 'package:invoiceninja_flutter/redux/static/static_state.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:memoize/memoize.dart';
import 'package:built_collection/built_collection.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/ui/list_ui_state.dart';
var memoizedDropdownScheduleList = memo5(
(BuiltMap<String, ScheduleEntity> scheduleMap,
BuiltList<String> scheduleList,
StaticState staticState,
BuiltMap<String, UserEntity> userMap,
String clientId) =>
dropdownSchedulesSelector(
scheduleMap, scheduleList, staticState, userMap, clientId));
List<String> dropdownSchedulesSelector(
BuiltMap<String, ScheduleEntity> scheduleMap,
BuiltList<String> scheduleList,
StaticState staticState,
BuiltMap<String, UserEntity> userMap,
String clientId) {
final list = scheduleList.where((scheduleId) {
final schedule = scheduleMap[scheduleId];
/*
if (clientId != null && clientId > 0 && schedule.clientId != clientId) {
return false;
}
*/
return schedule.isActive;
}).toList();
list.sort((scheduleAId, scheduleBId) {
final scheduleA = scheduleMap[scheduleAId];
final scheduleB = scheduleMap[scheduleBId];
return scheduleA.compareTo(scheduleB, ScheduleFields.name, true);
});
return list;
}
var memoizedFilteredScheduleList = memo4((SelectionState selectionState,
BuiltMap<String, ScheduleEntity> scheduleMap,
BuiltList<String> scheduleList,
ListUIState scheduleListState) =>
filteredSchedulesSelector(
selectionState, scheduleMap, scheduleList, scheduleListState));
List<String> filteredSchedulesSelector(
SelectionState selectionState,
BuiltMap<String, ScheduleEntity> scheduleMap,
BuiltList<String> scheduleList,
ListUIState scheduleListState) {
final filterEntityId = selectionState.filterEntityId;
//final filterEntityType = selectionState.filterEntityType;
final list = scheduleList.where((scheduleId) {
final schedule = scheduleMap[scheduleId];
if (filterEntityId != null && schedule.id != filterEntityId) {
return false;
} else {}
if (!schedule.matchesStates(scheduleListState.stateFilters)) {
return false;
}
return schedule.matchesFilter(scheduleListState.filter);
}).toList();
list.sort((scheduleAId, scheduleBId) {
final scheduleA = scheduleMap[scheduleAId];
final scheduleB = scheduleMap[scheduleBId];
return scheduleA.compareTo(scheduleB, scheduleListState.sortField,
scheduleListState.sortAscending);
});
return list;
}

View File

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

View File

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

View File

@ -40,6 +40,8 @@ import 'package:invoiceninja_flutter/redux/vendor/vendor_actions.dart';
import 'package:invoiceninja_flutter/redux/webhook/webhook_actions.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/redux/schedule/schedule_actions.dart';
import 'package:invoiceninja_flutter/redux/transaction_rule/transaction_rule_actions.dart';
import 'package:invoiceninja_flutter/redux/transaction/transaction_actions.dart';
@ -570,6 +572,17 @@ Reducer<BuiltList<HistoryRecord>> historyReducer = combineReducers([
_addToHistory(historyList,
HistoryRecord(id: action.group.id, entityType: EntityType.group))),
// STARTER: history - do not remove comment
TypedReducer<BuiltList<HistoryRecord>, ViewSchedule>((historyList, action) =>
_addToHistory(
historyList,
HistoryRecord(
id: action.scheduleId, entityType: EntityType.schedule))),
TypedReducer<BuiltList<HistoryRecord>, EditSchedule>((historyList, action) =>
_addToHistory(
historyList,
HistoryRecord(
id: action.schedule.id, entityType: EntityType.schedule))),
TypedReducer<BuiltList<HistoryRecord>, ViewTransactionRule>(
(historyList, action) => _addToHistory(
historyList,

View File

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

View File

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

View File

@ -53,6 +53,9 @@ class _$UIStateSerializer implements StructuredSerializer<UIState> {
'invoiceUIState',
serializers.serialize(object.invoiceUIState,
specifiedType: const FullType(InvoiceUIState)),
'scheduleUIState',
serializers.serialize(object.scheduleUIState,
specifiedType: const FullType(ScheduleUIState)),
'transactionRuleUIState',
serializers.serialize(object.transactionRuleUIState,
specifiedType: const FullType(TransactionRuleUIState)),
@ -221,6 +224,11 @@ class _$UIStateSerializer implements StructuredSerializer<UIState> {
result.invoiceUIState.replace(serializers.deserialize(value,
specifiedType: const FullType(InvoiceUIState)) as InvoiceUIState);
break;
case 'scheduleUIState':
result.scheduleUIState.replace(serializers.deserialize(value,
specifiedType: const FullType(ScheduleUIState))
as ScheduleUIState);
break;
case 'transactionRuleUIState':
result.transactionRuleUIState.replace(serializers.deserialize(value,
specifiedType: const FullType(TransactionRuleUIState))
@ -377,6 +385,8 @@ class _$UIState extends UIState {
@override
final InvoiceUIState invoiceUIState;
@override
final ScheduleUIState scheduleUIState;
@override
final TransactionRuleUIState transactionRuleUIState;
@override
final TransactionUIState transactionUIState;
@ -448,6 +458,7 @@ class _$UIState extends UIState {
this.productUIState,
this.clientUIState,
this.invoiceUIState,
this.scheduleUIState,
this.transactionRuleUIState,
this.transactionUIState,
this.bankAccountUIState,
@ -498,6 +509,8 @@ class _$UIState extends UIState {
clientUIState, 'UIState', 'clientUIState');
BuiltValueNullFieldError.checkNotNull(
invoiceUIState, 'UIState', 'invoiceUIState');
BuiltValueNullFieldError.checkNotNull(
scheduleUIState, 'UIState', 'scheduleUIState');
BuiltValueNullFieldError.checkNotNull(
transactionRuleUIState, 'UIState', 'transactionRuleUIState');
BuiltValueNullFieldError.checkNotNull(
@ -578,6 +591,7 @@ class _$UIState extends UIState {
productUIState == other.productUIState &&
clientUIState == other.clientUIState &&
invoiceUIState == other.invoiceUIState &&
scheduleUIState == other.scheduleUIState &&
transactionRuleUIState == other.transactionRuleUIState &&
transactionUIState == other.transactionUIState &&
bankAccountUIState == other.bankAccountUIState &&
@ -628,7 +642,7 @@ class _$UIState extends UIState {
$jc(
$jc(
$jc(
$jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc(0, selectedCompanyIndex.hashCode), currentRoute.hashCode), previousRoute.hashCode), loadingEntityType.hashCode), previewStack.hashCode), filterStack.hashCode), filter.hashCode), filterClearedAt.hashCode), lastActivityAt.hashCode), dashboardUIState.hashCode), productUIState.hashCode), clientUIState.hashCode), invoiceUIState.hashCode), transactionRuleUIState.hashCode), transactionUIState.hashCode), bankAccountUIState.hashCode), purchaseOrderUIState.hashCode), recurringExpenseUIState.hashCode), subscriptionUIState.hashCode), taskStatusUIState.hashCode), expenseCategoryUIState.hashCode),
$jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc(0, selectedCompanyIndex.hashCode), currentRoute.hashCode), previousRoute.hashCode), loadingEntityType.hashCode), previewStack.hashCode), filterStack.hashCode), filter.hashCode), filterClearedAt.hashCode), lastActivityAt.hashCode), dashboardUIState.hashCode), productUIState.hashCode), clientUIState.hashCode), invoiceUIState.hashCode), scheduleUIState.hashCode), transactionRuleUIState.hashCode), transactionUIState.hashCode), bankAccountUIState.hashCode), purchaseOrderUIState.hashCode), recurringExpenseUIState.hashCode), subscriptionUIState.hashCode), taskStatusUIState.hashCode), expenseCategoryUIState.hashCode),
recurringInvoiceUIState.hashCode),
webhookUIState.hashCode),
tokenUIState.hashCode),
@ -666,6 +680,7 @@ class _$UIState extends UIState {
..add('productUIState', productUIState)
..add('clientUIState', clientUIState)
..add('invoiceUIState', invoiceUIState)
..add('scheduleUIState', scheduleUIState)
..add('transactionRuleUIState', transactionRuleUIState)
..add('transactionUIState', transactionUIState)
..add('bankAccountUIState', bankAccountUIState)
@ -769,6 +784,12 @@ class UIStateBuilder implements Builder<UIState, UIStateBuilder> {
set invoiceUIState(InvoiceUIStateBuilder invoiceUIState) =>
_$this._invoiceUIState = invoiceUIState;
ScheduleUIStateBuilder _scheduleUIState;
ScheduleUIStateBuilder get scheduleUIState =>
_$this._scheduleUIState ??= new ScheduleUIStateBuilder();
set scheduleUIState(ScheduleUIStateBuilder scheduleUIState) =>
_$this._scheduleUIState = scheduleUIState;
TransactionRuleUIStateBuilder _transactionRuleUIState;
TransactionRuleUIStateBuilder get transactionRuleUIState =>
_$this._transactionRuleUIState ??= new TransactionRuleUIStateBuilder();
@ -956,6 +977,7 @@ class UIStateBuilder implements Builder<UIState, UIStateBuilder> {
_productUIState = $v.productUIState.toBuilder();
_clientUIState = $v.clientUIState.toBuilder();
_invoiceUIState = $v.invoiceUIState.toBuilder();
_scheduleUIState = $v.scheduleUIState.toBuilder();
_transactionRuleUIState = $v.transactionRuleUIState.toBuilder();
_transactionUIState = $v.transactionUIState.toBuilder();
_bankAccountUIState = $v.bankAccountUIState.toBuilder();
@ -1023,6 +1045,7 @@ class UIStateBuilder implements Builder<UIState, UIStateBuilder> {
productUIState: productUIState.build(),
clientUIState: clientUIState.build(),
invoiceUIState: invoiceUIState.build(),
scheduleUIState: scheduleUIState.build(),
transactionRuleUIState: transactionRuleUIState.build(),
transactionUIState: transactionUIState.build(),
bankAccountUIState: bankAccountUIState.build(),
@ -1066,6 +1089,8 @@ class UIStateBuilder implements Builder<UIState, UIStateBuilder> {
clientUIState.build();
_$failedField = 'invoiceUIState';
invoiceUIState.build();
_$failedField = 'scheduleUIState';
scheduleUIState.build();
_$failedField = 'transactionRuleUIState';
transactionRuleUIState.build();
_$failedField = 'transactionUIState';

View File

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

View File

@ -0,0 +1,111 @@
import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/ui/app/edit_scaffold.dart';
import 'package:invoiceninja_flutter/ui/app/form_card.dart';
import 'package:invoiceninja_flutter/ui/schedule/edit/schedule_edit_vm.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/ui/app/scrollable_listview.dart';
class ScheduleEdit extends StatefulWidget {
const ScheduleEdit({
Key key,
@required this.viewModel,
}) : super(key: key);
final ScheduleEditVM viewModel;
@override
_ScheduleEditState createState() => _ScheduleEditState();
}
class _ScheduleEditState extends State<ScheduleEdit> {
static final GlobalKey<FormState> _formKey =
GlobalKey<FormState>(debugLabel: '_scheduleEdit');
final _debouncer = Debouncer();
// STARTER: controllers - do not remove comment
final _schedulesController = TextEditingController();
List<TextEditingController> _controllers = [];
@override
void didChangeDependencies() {
_controllers = [
// STARTER: array - do not remove comment
_schedulesController,
];
_controllers.forEach((controller) => controller.removeListener(_onChanged));
final schedule = widget.viewModel.schedule;
// STARTER: read value - do not remove comment
_schedulesController.text = schedule.name;
_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 schedule = widget.viewModel.schedule.rebuild((b) => b
// STARTER: set value - do not remove comment
..schedules = _schedulesController.text.trim());
if (schedule != widget.viewModel.schedule) {
widget.viewModel.onChanged(schedule);
}
});
}
@override
Widget build(BuildContext context) {
final viewModel = widget.viewModel;
final localization = AppLocalization.of(context);
final schedule = viewModel.schedule;
return EditScaffold(
title:
schedule.isNew ? localization.newSchedule : localization.editSchedule,
onCancelPressed: (context) => viewModel.onCancelPressed(context),
onSavePressed: (context) {
final bool isValid = _formKey.currentState.validate();
if (!isValid) {
return;
}
viewModel.onSavePressed(context);
},
body: Form(
key: _formKey,
child: Builder(builder: (BuildContext context) {
return ScrollableListView(
children: <Widget>[
FormCard(
children: <Widget>[
// STARTER: widgets - do not remove comment
TextFormField(
controller: _schedulesController,
autocorrect: false,
decoration: InputDecoration(
labelText: 'Schedules',
),
),
],
),
],
);
})),
);
}
}

View File

@ -0,0 +1,116 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:invoiceninja_flutter/redux/ui/ui_actions.dart';
import 'package:redux/redux.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/ui/app/dialogs/error_dialog.dart';
import 'package:invoiceninja_flutter/ui/schedule/view/schedule_view_vm.dart';
import 'package:invoiceninja_flutter/redux/schedule/schedule_actions.dart';
import 'package:invoiceninja_flutter/ui/schedule/edit/schedule_edit.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:flutter_styled_toast/flutter_styled_toast.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
class ScheduleEditScreen extends StatelessWidget {
const ScheduleEditScreen({Key key}) : super(key: key);
static const String route = '/schedule/edit';
@override
Widget build(BuildContext context) {
return StoreConnector<AppState, ScheduleEditVM>(
converter: (Store<AppState> store) {
return ScheduleEditVM.fromStore(store);
},
builder: (context, viewModel) {
return ScheduleEdit(
viewModel: viewModel,
key: ValueKey(viewModel.schedule.updatedAt),
);
},
);
}
}
class ScheduleEditVM {
ScheduleEditVM({
@required this.state,
@required this.schedule,
@required this.company,
@required this.onChanged,
@required this.isSaving,
@required this.origSchedule,
@required this.onSavePressed,
@required this.onCancelPressed,
@required this.isLoading,
});
factory ScheduleEditVM.fromStore(Store<AppState> store) {
final state = store.state;
final schedule = state.scheduleUIState.editing;
return ScheduleEditVM(
state: state,
isLoading: state.isLoading,
isSaving: state.isSaving,
origSchedule: state.scheduleState.map[schedule.id],
schedule: schedule,
company: state.company,
onChanged: (ScheduleEntity schedule) {
store.dispatch(UpdateSchedule(schedule));
},
onCancelPressed: (BuildContext context) {
createEntity(context: context, entity: ScheduleEntity(), force: true);
if (state.scheduleUIState.cancelCompleter != null) {
state.scheduleUIState.cancelCompleter.complete();
} else {
store.dispatch(UpdateCurrentRoute(state.uiState.previousRoute));
}
},
onSavePressed: (BuildContext context) {
Debouncer.runOnComplete(() {
final schedule = store.state.scheduleUIState.editing;
final localization = AppLocalization.of(context);
final Completer<ScheduleEntity> completer =
new Completer<ScheduleEntity>();
store.dispatch(
SaveScheduleRequest(completer: completer, schedule: schedule));
return completer.future.then((savedSchedule) {
showToast(schedule.isNew
? localization.createdSchedule
: localization.updatedSchedule);
if (state.prefState.isMobile) {
store.dispatch(UpdateCurrentRoute(ScheduleViewScreen.route));
if (schedule.isNew) {
Navigator.of(context)
.pushReplacementNamed(ScheduleViewScreen.route);
} else {
Navigator.of(context).pop(savedSchedule);
}
} else {
viewEntity(entity: savedSchedule, force: true);
}
}).catchError((Object error) {
showDialog<ErrorDialog>(
context: context,
builder: (BuildContext context) {
return ErrorDialog(error);
});
});
});
},
);
}
final ScheduleEntity schedule;
final CompanyEntity company;
final Function(ScheduleEntity) onChanged;
final Function(BuildContext) onSavePressed;
final Function(BuildContext) onCancelPressed;
final bool isLoading;
final bool isSaving;
final ScheduleEntity origSchedule;
final AppState state;
}

View File

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

View File

@ -0,0 +1,120 @@
import 'dart:async';
import 'package:invoiceninja_flutter/ui/app/tables/entity_list.dart';
import 'package:invoiceninja_flutter/ui/schedule/schedule_list_item.dart';
import 'package:invoiceninja_flutter/ui/schedule/schedule_presenter.dart';
import 'package:redux/redux.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:built_collection/built_collection.dart';
import 'package:invoiceninja_flutter/redux/ui/list_ui_state.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/redux/schedule/schedule_selectors.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/schedule/schedule_actions.dart';
class ScheduleListBuilder extends StatelessWidget {
const ScheduleListBuilder({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return StoreConnector<AppState, ScheduleListVM>(
converter: ScheduleListVM.fromStore,
builder: (context, viewModel) {
return EntityList(
entityType: EntityType.schedule,
presenter: SchedulePresenter(),
state: viewModel.state,
entityList: viewModel.scheduleList,
tableColumns: viewModel.tableColumns,
onRefreshed: viewModel.onRefreshed,
onSortColumn: viewModel.onSortColumn,
onClearMultiselect: viewModel.onClearMultielsect,
itemBuilder: (BuildContext context, index) {
final state = viewModel.state;
final scheduleId = viewModel.scheduleList[index];
final schedule = viewModel.scheduleMap[scheduleId];
final listState = state.getListState(EntityType.schedule);
final isInMultiselect = listState.isInMultiselect();
return ScheduleListItem(
user: viewModel.state.user,
filter: viewModel.filter,
schedule: schedule,
isChecked: isInMultiselect && listState.isSelected(schedule.id),
);
});
},
);
}
}
class ScheduleListVM {
ScheduleListVM({
@required this.state,
@required this.userCompany,
@required this.scheduleList,
@required this.scheduleMap,
@required this.filter,
@required this.isLoading,
@required this.listState,
@required this.onRefreshed,
@required this.onEntityAction,
@required this.tableColumns,
@required this.onSortColumn,
@required this.onClearMultielsect,
});
static ScheduleListVM fromStore(Store<AppState> store) {
Future<Null> _handleRefresh(BuildContext context) {
if (store.state.isLoading) {
return Future<Null>(null);
}
final completer = snackBarCompleter<Null>(
context, AppLocalization.of(context).refreshComplete);
store.dispatch(RefreshData(completer: completer));
return completer.future;
}
final state = store.state;
return ScheduleListVM(
state: state,
userCompany: state.userCompany,
listState: state.scheduleListState,
scheduleList: memoizedFilteredScheduleList(
state.getUISelection(EntityType.schedule),
state.scheduleState.map,
state.scheduleState.list,
state.scheduleListState),
scheduleMap: state.scheduleState.map,
isLoading: state.isLoading,
filter: state.scheduleUIState.listUIState.filter,
onEntityAction: (BuildContext context, List<BaseEntity> schedules,
EntityAction action) =>
handleScheduleAction(context, schedules, action),
onRefreshed: (context) => _handleRefresh(context),
tableColumns:
state.userCompany.settings?.getTableColumns(EntityType.schedule) ??
SchedulePresenter.getDefaultTableFields(state.userCompany),
onSortColumn: (field) => store.dispatch(SortSchedules(field)),
onClearMultielsect: () => store.dispatch(ClearScheduleMultiselect()),
);
}
final AppState state;
final UserCompanyEntity userCompany;
final List<String> scheduleList;
final BuiltMap<String, ScheduleEntity> scheduleMap;
final ListUIState listState;
final String filter;
final bool isLoading;
final Function(BuildContext) onRefreshed;
final Function(BuildContext, List<BaseEntity>, EntityAction) onEntityAction;
final List<String> tableColumns;
final Function(String) onSortColumn;
final Function onClearMultielsect;
}

View File

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

View File

@ -0,0 +1,104 @@
import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/schedule/schedule_actions.dart';
import 'package:invoiceninja_flutter/ui/app/app_bottom_bar.dart';
import 'package:invoiceninja_flutter/ui/app/list_scaffold.dart';
import 'package:invoiceninja_flutter/ui/app/list_filter.dart';
import 'package:invoiceninja_flutter/ui/schedule/schedule_list_vm.dart';
import 'package:invoiceninja_flutter/ui/schedule/schedule_presenter.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
import 'schedule_screen_vm.dart';
class ScheduleScreen extends StatelessWidget {
const ScheduleScreen({
Key key,
@required this.viewModel,
}) : super(key: key);
static const String route = '/schedule';
final ScheduleScreenVM viewModel;
@override
Widget build(BuildContext context) {
final store = StoreProvider.of<AppState>(context);
final state = store.state;
final userCompany = state.userCompany;
final localization = AppLocalization.of(context);
return ListScaffold(
entityType: EntityType.schedule,
onHamburgerLongPress: () => store.dispatch(StartScheduleMultiselect()),
appBarTitle: ListFilter(
key: ValueKey('__filter_${state.scheduleListState.filterClearedAt}__'),
entityType: EntityType.schedule,
entityIds: viewModel.scheduleList,
filter: state.scheduleListState.filter,
onFilterChanged: (value) {
store.dispatch(FilterSchedules(value));
},
onSelectedState: (EntityState state, value) {
store.dispatch(FilterSchedulesByState(state));
},
),
onCheckboxPressed: () {
if (store.state.scheduleListState.isInMultiselect()) {
store.dispatch(ClearScheduleMultiselect());
} else {
store.dispatch(StartScheduleMultiselect());
}
},
body: ScheduleListBuilder(),
bottomNavigationBar: AppBottomBar(
entityType: EntityType.schedule,
tableColumns: SchedulePresenter.getAllTableFields(userCompany),
defaultTableColumns:
SchedulePresenter.getDefaultTableFields(userCompany),
onSelectedSortField: (value) {
store.dispatch(SortSchedules(value));
},
sortFields: [
ScheduleFields.name,
],
onSelectedState: (EntityState state, value) {
store.dispatch(FilterSchedulesByState(state));
},
onCheckboxPressed: () {
if (store.state.scheduleListState.isInMultiselect()) {
store.dispatch(ClearScheduleMultiselect());
} else {
store.dispatch(StartScheduleMultiselect());
}
},
onSelectedCustom1: (value) =>
store.dispatch(FilterSchedulesByCustom1(value)),
onSelectedCustom2: (value) =>
store.dispatch(FilterSchedulesByCustom2(value)),
onSelectedCustom3: (value) =>
store.dispatch(FilterSchedulesByCustom3(value)),
onSelectedCustom4: (value) =>
store.dispatch(FilterSchedulesByCustom4(value)),
),
floatingActionButton: state.prefState.isMenuFloated &&
userCompany.canCreate(EntityType.schedule)
? FloatingActionButton(
heroTag: 'schedule_fab',
backgroundColor: Theme.of(context).primaryColorDark,
onPressed: () {
createEntityByType(
context: context, entityType: EntityType.schedule);
},
child: Icon(
Icons.add,
color: Colors.white,
),
tooltip: localization.newSchedule,
)
: null,
);
}
}

View File

@ -0,0 +1,62 @@
import 'package:built_collection/built_collection.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/schedule/schedule_actions.dart';
import 'package:invoiceninja_flutter/redux/schedule/schedule_selectors.dart';
import 'package:redux/redux.dart';
import 'schedule_screen.dart';
class ScheduleScreenBuilder extends StatelessWidget {
const ScheduleScreenBuilder({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return StoreConnector<AppState, ScheduleScreenVM>(
converter: ScheduleScreenVM.fromStore,
builder: (context, vm) {
return ScheduleScreen(
viewModel: vm,
);
},
);
}
}
class ScheduleScreenVM {
ScheduleScreenVM({
@required this.isInMultiselect,
@required this.scheduleList,
@required this.userCompany,
@required this.onEntityAction,
@required this.scheduleMap,
});
final bool isInMultiselect;
final UserCompanyEntity userCompany;
final List<String> scheduleList;
final Function(BuildContext, List<BaseEntity>, EntityAction) onEntityAction;
final BuiltMap<String, ScheduleEntity> scheduleMap;
static ScheduleScreenVM fromStore(Store<AppState> store) {
final state = store.state;
return ScheduleScreenVM(
scheduleMap: state.scheduleState.map,
scheduleList: memoizedFilteredScheduleList(
state.getUISelection(EntityType.schedule),
state.scheduleState.map,
state.scheduleState.list,
state.scheduleListState,
),
userCompany: state.userCompany,
isInMultiselect: state.scheduleListState.isInMultiselect(),
onEntityAction: (BuildContext context, List<BaseEntity> schedules,
EntityAction action) =>
handleScheduleAction(context, schedules, action),
);
}
}

View File

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

View File

@ -0,0 +1,91 @@
import 'dart:async';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:redux/redux.dart';
import 'package:invoiceninja_flutter/redux/ui/ui_actions.dart';
import 'package:invoiceninja_flutter/ui/schedule/schedule_screen.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/redux/schedule/schedule_actions.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/ui/schedule/view/schedule_view.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
class ScheduleViewScreen extends StatelessWidget {
const ScheduleViewScreen({
Key key,
this.isFilter = false,
}) : super(key: key);
static const String route = '/schedule/view';
final bool isFilter;
@override
Widget build(BuildContext context) {
return StoreConnector<AppState, ScheduleViewVM>(
converter: (Store<AppState> store) {
return ScheduleViewVM.fromStore(store);
},
builder: (context, vm) {
return ScheduleView(
viewModel: vm,
isFilter: isFilter,
);
},
);
}
}
class ScheduleViewVM {
ScheduleViewVM({
@required this.state,
@required this.schedule,
@required this.company,
@required this.onEntityAction,
@required this.onRefreshed,
@required this.isSaving,
@required this.isLoading,
@required this.isDirty,
@required this.onBackPressed,
});
factory ScheduleViewVM.fromStore(Store<AppState> store) {
final state = store.state;
final schedule =
state.scheduleState.map[state.scheduleUIState.selectedId] ??
ScheduleEntity(id: state.scheduleUIState.selectedId);
Future<Null> _handleRefresh(BuildContext context) {
final completer = snackBarCompleter<Null>(
context, AppLocalization.of(context).refreshComplete);
store.dispatch(
LoadSchedule(completer: completer, scheduleId: schedule.id));
return completer.future;
}
return ScheduleViewVM(
state: state,
company: state.company,
isSaving: state.isSaving,
isLoading: state.isLoading,
isDirty: schedule.isNew,
schedule: schedule,
onRefreshed: (context) => _handleRefresh(context),
onBackPressed: () {
store.dispatch(UpdateCurrentRoute(ScheduleScreen.route));
},
onEntityAction: (BuildContext context, EntityAction action) =>
handleEntitiesActions([schedule], action, autoPop: true),
);
}
final AppState state;
final ScheduleEntity schedule;
final CompanyEntity company;
final Function(BuildContext, EntityAction) onEntityAction;
final Function(BuildContext) onRefreshed;
final Function onBackPressed;
final bool isSaving;
final bool isLoading;
final bool isDirty;
}

View File

@ -16,6 +16,19 @@ mixin LocalizationsProvider on LocaleCodeAware {
static final Map<String, Map<String, String>> _localizedValues = {
'en': {
// STARTER: lang key - do not remove comment
'schedule': 'Schedule',
'schedules': 'Schedules',
'new_schedule': 'New Schedule',
'edit_schedule': 'Edit Schedule',
'created_schedule': 'Successfully created schedule',
'updated_schedule': 'Successfully updated schedule',
'archived_schedule': 'Successfully archived schedule',
'deleted_schedule': 'Successfully deleted schedule',
'removed_schedule': 'Successfully removed schedule',
'restored_schedule': 'Successfully restored schedule',
'search_schedule': 'Search Schedule',
'search_schedules': 'Search Schedules',
'archive_payment': 'Archive Payment',
'archive_invoice': 'Archive Invoice',
'archive_quote': 'Archive Quote',
@ -1556,7 +1569,6 @@ mixin LocalizationsProvider on LocaleCodeAware {
'payment_number': 'Payment Number',
'late_fee_amount': 'Late Fee Amount',
'late_fee_percent': 'Late Fee Percent',
'schedule': 'Schedule',
'before_due_date': 'Before the due date',
'after_due_date': 'After the due date',
'after_invoice_date': 'After the invoice date',
@ -94452,6 +94464,46 @@ mixin LocalizationsProvider on LocaleCodeAware {
_localizedValues[localeCode]['image_url'] ??
_localizedValues['en']['image_url'];
String get schedules =>
_localizedValues[localeCode]['schedules'] ??
_localizedValues['en']['schedules'];
String get newSchedule =>
_localizedValues[localeCode]['new_schedule'] ??
_localizedValues['en']['new_schedule'];
String get createdSchedule =>
_localizedValues[localeCode]['created_schedule'] ??
_localizedValues['en']['created_schedule'];
String get updatedSchedule =>
_localizedValues[localeCode]['updated_schedule'] ??
_localizedValues['en']['updated_schedule'];
String get archivedSchedule =>
_localizedValues[localeCode]['archived_schedule'] ??
_localizedValues['en']['archived_schedule'];
String get deletedSchedule =>
_localizedValues[localeCode]['deleted_schedule'] ??
_localizedValues['en']['deleted_schedule'];
String get restoredSchedule =>
_localizedValues[localeCode]['restored_schedule'] ??
_localizedValues['en']['restored_schedule'];
String get editSchedule =>
_localizedValues[localeCode]['edit_schedule'] ??
_localizedValues['en']['edit_schedule'];
String get searchSchedule =>
_localizedValues[localeCode]['search_schedule'] ??
_localizedValues['en']['search_schedule'];
String get searchSchedules =>
_localizedValues[localeCode]['search_schedules'] ??
_localizedValues['en']['search_schedules'];
// STARTER: lang field - do not remove comment
String lookup(String key) {