Null safety
This commit is contained in:
parent
96fea81865
commit
7b5bd7b68c
|
|
@ -34,7 +34,8 @@ class EntityListTile extends StatefulWidget {
|
||||||
final BaseEntity? entity;
|
final BaseEntity? entity;
|
||||||
final bool isFilter;
|
final bool isFilter;
|
||||||
final ClientEntity? client;
|
final ClientEntity? client;
|
||||||
final Function(BuildContext, BaseEntity?, EntityAction)? onEntityActionSelected;
|
final Function(BuildContext, BaseEntity?, EntityAction)?
|
||||||
|
onEntityActionSelected;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_EntityListTileState createState() => _EntityListTileState();
|
_EntityListTileState createState() => _EntityListTileState();
|
||||||
|
|
@ -64,8 +65,9 @@ class _EntityListTileState extends State<EntityListTile> {
|
||||||
_isHovered;
|
_isHovered;
|
||||||
|
|
||||||
final leading = ActionMenuButton(
|
final leading = ActionMenuButton(
|
||||||
iconData:
|
iconData: isHovered
|
||||||
isHovered ? Icons.more_vert : getEntityIcon(widget.entity!.entityType),
|
? Icons.more_vert
|
||||||
|
: getEntityIcon(widget.entity!.entityType),
|
||||||
iconSize: isHovered ? null : 18,
|
iconSize: isHovered ? null : 18,
|
||||||
entityActions: widget.entity!.getActions(
|
entityActions: widget.entity!.getActions(
|
||||||
userCompany: state.userCompany,
|
userCompany: state.userCompany,
|
||||||
|
|
@ -146,7 +148,7 @@ class _EntityListTileState extends State<EntityListTile> {
|
||||||
onLongPress: () =>
|
onLongPress: () =>
|
||||||
inspectEntity(entity: widget.entity, longPress: true),
|
inspectEntity(entity: widget.entity, longPress: true),
|
||||||
title: Text(
|
title: Text(
|
||||||
EntityPresenter().initialize(widget.entity, context).title()!,
|
EntityPresenter().initialize(widget.entity!, context).title()!,
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
|
|
@ -166,8 +168,8 @@ class _EntityListTileState extends State<EntityListTile> {
|
||||||
: null,
|
: null,
|
||||||
leading: leading,
|
leading: leading,
|
||||||
trailing: trailing,
|
trailing: trailing,
|
||||||
isThreeLine:
|
isThreeLine: (widget.subtitle ?? '').isNotEmpty &&
|
||||||
(widget.subtitle ?? '').isNotEmpty && !widget.entity!.isActive,
|
!widget.entity!.isActive,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ListDivider(),
|
ListDivider(),
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,8 @@ class EntityTopFilter extends StatelessWidget {
|
||||||
constraints: BoxConstraints(maxWidth: 220),
|
constraints: BoxConstraints(maxWidth: 220),
|
||||||
child: Text(
|
child: Text(
|
||||||
EntityPresenter()
|
EntityPresenter()
|
||||||
.initialize(filterEntity as BaseEntity?, context)
|
.initialize(
|
||||||
|
filterEntity as BaseEntity, context)
|
||||||
.title()!,
|
.title()!,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 17,
|
fontSize: 17,
|
||||||
|
|
@ -153,7 +154,8 @@ class EntityTopFilter extends StatelessWidget {
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
viewEntitiesByType(
|
viewEntitiesByType(
|
||||||
entityType: relatedTypes[i],
|
entityType: relatedTypes[i],
|
||||||
filterEntity: filterEntity as BaseEntity?,
|
filterEntity:
|
||||||
|
filterEntity as BaseEntity?,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
onLongPress: () {
|
onLongPress: () {
|
||||||
|
|
@ -206,7 +208,8 @@ class EntityTopFilter extends StatelessWidget {
|
||||||
} else {
|
} else {
|
||||||
viewEntitiesByType(
|
viewEntitiesByType(
|
||||||
entityType: value,
|
entityType: value,
|
||||||
filterEntity: filterEntity as BaseEntity?,
|
filterEntity:
|
||||||
|
filterEntity as BaseEntity?,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ class _TaxRateDropdownState extends State<TaxRateDropdown> {
|
||||||
value: taxRate,
|
value: taxRate,
|
||||||
isExpanded: true,
|
isExpanded: true,
|
||||||
isDense: true,
|
isDense: true,
|
||||||
onChanged: widget.onSelected,
|
onChanged: (rate) => widget.onSelected(rate!),
|
||||||
items: [
|
items: [
|
||||||
if (!taxRate.isEmpty)
|
if (!taxRate.isEmpty)
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,10 @@ import 'package:invoiceninja_flutter/utils/formatting.dart';
|
||||||
import 'package:invoiceninja_flutter/utils/localization.dart';
|
import 'package:invoiceninja_flutter/utils/localization.dart';
|
||||||
|
|
||||||
class EntityPresenter {
|
class EntityPresenter {
|
||||||
EntityPresenter initialize(BaseEntity? entity, BuildContext context) {
|
EntityPresenter initialize(
|
||||||
|
BaseEntity entity,
|
||||||
|
BuildContext context,
|
||||||
|
) {
|
||||||
this.entity = entity;
|
this.entity = entity;
|
||||||
this.context = context;
|
this.context = context;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ class EntityDataTableSource extends AppDataTableSource {
|
||||||
DataRow getRow(int index) {
|
DataRow getRow(int index) {
|
||||||
final state = StoreProvider.of<AppState>(context).state;
|
final state = StoreProvider.of<AppState>(context).state;
|
||||||
final prefState = state.prefState;
|
final prefState = state.prefState;
|
||||||
final entity = entityMap![entityList[index]];
|
final entity = entityMap![entityList[index]]!;
|
||||||
entityPresenter!.initialize(entity, context);
|
entityPresenter!.initialize(entity, context);
|
||||||
|
|
||||||
final listState = state.getListState(entityType);
|
final listState = state.getListState(entityType);
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ class ViewScaffold extends StatelessWidget {
|
||||||
});
|
});
|
||||||
|
|
||||||
final bool isFilter;
|
final bool isFilter;
|
||||||
final BaseEntity? entity;
|
final BaseEntity entity;
|
||||||
final Widget body;
|
final Widget body;
|
||||||
final Function? onBackPressed;
|
final Function? onBackPressed;
|
||||||
final Widget? appBarBottom;
|
final Widget? appBarBottom;
|
||||||
|
|
@ -105,7 +105,7 @@ class ViewScaffold extends StatelessWidget {
|
||||||
child: Text(appBarTitle!),
|
child: Text(appBarTitle!),
|
||||||
),
|
),
|
||||||
bottom: appBarBottom as PreferredSizeWidget?,
|
bottom: appBarBottom as PreferredSizeWidget?,
|
||||||
actions: entity!.isNew
|
actions: entity.isNew
|
||||||
? []
|
? []
|
||||||
: [
|
: [
|
||||||
if (isSettings && isDesktop(context) && !isFilter)
|
if (isSettings && isDesktop(context) && !isFilter)
|
||||||
|
|
|
||||||
|
|
@ -101,8 +101,10 @@ class CompanyGatewayEditVM {
|
||||||
store.dispatch(SaveCompanyRequest(
|
store.dispatch(SaveCompanyRequest(
|
||||||
completer: Completer<Null>(),
|
completer: Completer<Null>(),
|
||||||
company: company.rebuild((b) => b
|
company: company.rebuild((b) => b
|
||||||
..settings.companyGatewayIds +=
|
..settings.companyGatewayIds =
|
||||||
',' + savedCompanyGateway.id)));
|
company.settings.companyGatewayIds! +
|
||||||
|
',' +
|
||||||
|
savedCompanyGateway.id)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.prefState.isMobile) {
|
if (state.prefState.isMobile) {
|
||||||
|
|
|
||||||
|
|
@ -57,8 +57,8 @@ class CreditEditDetailsVM extends EntityEditDetailsVM {
|
||||||
CompanyEntity? company,
|
CompanyEntity? company,
|
||||||
InvoiceEntity? invoice,
|
InvoiceEntity? invoice,
|
||||||
Function(InvoiceEntity)? onChanged,
|
Function(InvoiceEntity)? onChanged,
|
||||||
Function(BuildContext, InvoiceEntity, ClientEntity)? onClientChanged,
|
Function(BuildContext, InvoiceEntity, ClientEntity?)? onClientChanged,
|
||||||
Function(BuildContext, InvoiceEntity, VendorEntity)? onVendorChanged,
|
Function(BuildContext, InvoiceEntity, VendorEntity?)? onVendorChanged,
|
||||||
BuiltMap<String?, ClientEntity?>? clientMap,
|
BuiltMap<String?, ClientEntity?>? clientMap,
|
||||||
BuiltList<String>? clientList,
|
BuiltList<String>? clientList,
|
||||||
Function(BuildContext context, Completer<SelectableEntity> completer)?
|
Function(BuildContext context, Completer<SelectableEntity> completer)?
|
||||||
|
|
@ -91,7 +91,9 @@ class CreditEditDetailsVM extends EntityEditDetailsVM {
|
||||||
clientMap: state.clientState.map,
|
clientMap: state.clientState.map,
|
||||||
clientList: state.clientState.list,
|
clientList: state.clientState.list,
|
||||||
onClientChanged: (context, credit, client) {
|
onClientChanged: (context, credit, client) {
|
||||||
store.dispatch(UpdateCredit(credit.applyClient(state, client)));
|
if (client != null) {
|
||||||
|
store.dispatch(UpdateCredit(credit.applyClient(state, client)));
|
||||||
|
}
|
||||||
store.dispatch(UpdateCreditClient(client: client));
|
store.dispatch(UpdateCreditClient(client: client));
|
||||||
},
|
},
|
||||||
onAddClientPressed: (context, completer) {
|
onAddClientPressed: (context, completer) {
|
||||||
|
|
|
||||||
|
|
@ -52,8 +52,8 @@ class CreditEditVM extends AbstractInvoiceEditVM {
|
||||||
InvoiceEntity? invoice,
|
InvoiceEntity? invoice,
|
||||||
int? invoiceItemIndex,
|
int? invoiceItemIndex,
|
||||||
InvoiceEntity? origInvoice,
|
InvoiceEntity? origInvoice,
|
||||||
Function(BuildContext, [EntityAction])? onSavePressed,
|
Function(BuildContext, [EntityAction?])? onSavePressed,
|
||||||
Function(List<InvoiceItemEntity>, String, String)? onItemsAdded,
|
Function(List<InvoiceItemEntity>, String?, String?)? onItemsAdded,
|
||||||
bool? isSaving,
|
bool? isSaving,
|
||||||
Function(BuildContext)? onCancelPressed,
|
Function(BuildContext)? onCancelPressed,
|
||||||
Function(BuildContext, List<MultipartFile>, bool?)? onUploadDocuments,
|
Function(BuildContext, List<MultipartFile>, bool?)? onUploadDocuments,
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ class AbstractExpenseViewVM {
|
||||||
});
|
});
|
||||||
|
|
||||||
final AppState? state;
|
final AppState? state;
|
||||||
final ExpenseEntity? expense;
|
final ExpenseEntity expense;
|
||||||
final CompanyEntity? company;
|
final CompanyEntity? company;
|
||||||
final Function(BuildContext, EntityAction)? onEntityAction;
|
final Function(BuildContext, EntityAction)? onEntityAction;
|
||||||
final Function(BuildContext)? onRefreshed;
|
final Function(BuildContext)? onRefreshed;
|
||||||
|
|
@ -73,8 +73,8 @@ class AbstractExpenseViewVM {
|
||||||
|
|
||||||
class ExpenseViewVM extends AbstractExpenseViewVM {
|
class ExpenseViewVM extends AbstractExpenseViewVM {
|
||||||
ExpenseViewVM({
|
ExpenseViewVM({
|
||||||
|
required ExpenseEntity expense,
|
||||||
AppState? state,
|
AppState? state,
|
||||||
ExpenseEntity? expense,
|
|
||||||
CompanyEntity? company,
|
CompanyEntity? company,
|
||||||
Function(BuildContext, EntityAction)? onEntityAction,
|
Function(BuildContext, EntityAction)? onEntityAction,
|
||||||
Function(BuildContext)? onRefreshed,
|
Function(BuildContext)? onRefreshed,
|
||||||
|
|
|
||||||
|
|
@ -330,7 +330,7 @@ class InvoiceEditDesktopState extends State<InvoiceEditDesktop>
|
||||||
EntityPresenter()
|
EntityPresenter()
|
||||||
.initialize(
|
.initialize(
|
||||||
invoice.isPurchaseOrder
|
invoice.isPurchaseOrder
|
||||||
? vendor
|
? vendor!
|
||||||
: client,
|
: client,
|
||||||
context)
|
context)
|
||||||
.title()!,
|
.title()!,
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ class _InvoiceEditItemsState extends State<InvoiceEditItems> {
|
||||||
viewModel: viewModel,
|
viewModel: viewModel,
|
||||||
entityViewModel: widget.entityViewModel,
|
entityViewModel: widget.entityViewModel,
|
||||||
key: ValueKey('__${lineItemIndex}__'),
|
key: ValueKey('__${lineItemIndex}__'),
|
||||||
invoiceItem: invoice.lineItems[lineItemIndex!],
|
invoiceItem: invoice.lineItems[lineItemIndex!]!,
|
||||||
index: lineItemIndex,
|
index: lineItemIndex,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
@ -97,8 +97,8 @@ class ItemEditDetails extends StatefulWidget {
|
||||||
required this.entityViewModel,
|
required this.entityViewModel,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final int? index;
|
final int index;
|
||||||
final InvoiceItemEntity? invoiceItem;
|
final InvoiceItemEntity invoiceItem;
|
||||||
final EntityEditItemsVM viewModel;
|
final EntityEditItemsVM viewModel;
|
||||||
final AbstractInvoiceEditVM entityViewModel;
|
final AbstractInvoiceEditVM entityViewModel;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
// Flutter imports:
|
// Flutter imports:
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
// Package imports:
|
// Package imports:
|
||||||
|
|
@ -676,8 +678,10 @@ class _InvoiceEditItemsDesktopState extends State<InvoiceEditItemsDesktop> {
|
||||||
return <ProductEntity>[];
|
return <ProductEntity>[];
|
||||||
}
|
}
|
||||||
|
|
||||||
return options as FutureOr<Iterable<ProductEntity>>;
|
return options
|
||||||
} as FutureOr<Iterable<ProductEntity>> Function(TextEditingValue),
|
as FutureOr<Iterable<ProductEntity>>;
|
||||||
|
} as FutureOr<Iterable<ProductEntity>> Function(
|
||||||
|
TextEditingValue),
|
||||||
displayStringForOption: (product) =>
|
displayStringForOption: (product) =>
|
||||||
product.productKey,
|
product.productKey,
|
||||||
onSelected: (product) {
|
onSelected: (product) {
|
||||||
|
|
@ -818,8 +822,8 @@ class _InvoiceEditItemsDesktopState extends State<InvoiceEditItemsDesktop> {
|
||||||
.cardColor,
|
.cardColor,
|
||||||
child:
|
child:
|
||||||
EntityAutocompleteListTile(
|
EntityAutocompleteListTile(
|
||||||
onTap: (entity) =>
|
onTap: (entity) => onSelected(
|
||||||
onSelected(entity as ProductEntity),
|
entity as ProductEntity),
|
||||||
overrideSuggestedAmount:
|
overrideSuggestedAmount:
|
||||||
(entity) {
|
(entity) {
|
||||||
final product =
|
final product =
|
||||||
|
|
@ -1162,6 +1166,8 @@ class _InvoiceEditItemsDesktopState extends State<InvoiceEditItemsDesktop> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
return SizedBox();
|
||||||
}
|
}
|
||||||
}).toList(),
|
}).toList(),
|
||||||
Padding(
|
Padding(
|
||||||
|
|
|
||||||
|
|
@ -78,8 +78,8 @@ class InvoiceEditVM extends AbstractInvoiceEditVM {
|
||||||
InvoiceEntity? invoice,
|
InvoiceEntity? invoice,
|
||||||
int? invoiceItemIndex,
|
int? invoiceItemIndex,
|
||||||
InvoiceEntity? origInvoice,
|
InvoiceEntity? origInvoice,
|
||||||
Function(BuildContext, [EntityAction])? onSavePressed,
|
Function(BuildContext, [EntityAction?])? onSavePressed,
|
||||||
Function(List<InvoiceItemEntity>, String, String)? onItemsAdded,
|
Function(List<InvoiceItemEntity>, String?, String?)? onItemsAdded,
|
||||||
bool? isSaving,
|
bool? isSaving,
|
||||||
Function(BuildContext)? onCancelPressed,
|
Function(BuildContext)? onCancelPressed,
|
||||||
Function(BuildContext, List<MultipartFile>, bool?)? onUploadDocuments,
|
Function(BuildContext, List<MultipartFile>, bool?)? onUploadDocuments,
|
||||||
|
|
@ -202,7 +202,7 @@ class InvoiceEditVM extends AbstractInvoiceEditVM {
|
||||||
},
|
},
|
||||||
onItemsAdded: (items, clientId, projectId) {
|
onItemsAdded: (items, clientId, projectId) {
|
||||||
if ((clientId ?? '').isNotEmpty || (projectId ?? '').isNotEmpty) {
|
if ((clientId ?? '').isNotEmpty || (projectId ?? '').isNotEmpty) {
|
||||||
final client = state.clientState.get(clientId);
|
final client = state.clientState.get(clientId!);
|
||||||
store.dispatch(UpdateInvoice(invoice.rebuild((b) => b
|
store.dispatch(UpdateInvoice(invoice.rebuild((b) => b
|
||||||
..clientId = clientId ?? ''
|
..clientId = clientId ?? ''
|
||||||
..projectId = projectId ?? ''
|
..projectId = projectId ?? ''
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
// Flutter imports:
|
// Flutter imports:
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
// Package imports:
|
// Package imports:
|
||||||
|
|
@ -111,7 +113,7 @@ class EmailInvoiceVM extends EmailEntityVM {
|
||||||
context, AppLocalization.of(context)!.emailedInvoice,
|
context, AppLocalization.of(context)!.emailedInvoice,
|
||||||
shouldPop: isMobile(context));
|
shouldPop: isMobile(context));
|
||||||
if (!isMobile(context)) {
|
if (!isMobile(context)) {
|
||||||
completer.future.then((value) {
|
completer.future.then<Null>(() {
|
||||||
viewEntity(entity: invoice);
|
viewEntity(entity: invoice);
|
||||||
} as FutureOr<Null> Function(Null));
|
} as FutureOr<Null> Function(Null));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -85,8 +85,8 @@ class ProjectViewVM {
|
||||||
client: client,
|
client: client,
|
||||||
onRefreshed: (context) => _handleRefresh(context),
|
onRefreshed: (context) => _handleRefresh(context),
|
||||||
onEntityPressed: (BuildContext context, EntityType entityType,
|
onEntityPressed: (BuildContext context, EntityType entityType,
|
||||||
{bool longPress = false}) {
|
{bool? longPress = false}) {
|
||||||
if (longPress && project.isActive && client.isActive) {
|
if (longPress == true && project.isActive && client.isActive) {
|
||||||
handleProjectAction(
|
handleProjectAction(
|
||||||
context, [project], EntityAction.newEntityType(entityType));
|
context, [project], EntityAction.newEntityType(entityType));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -52,8 +52,8 @@ class PurchaseOrderEditVM extends AbstractInvoiceEditVM {
|
||||||
InvoiceEntity? purchaseOrder,
|
InvoiceEntity? purchaseOrder,
|
||||||
int? invoiceItemIndex,
|
int? invoiceItemIndex,
|
||||||
InvoiceEntity? origInvoice,
|
InvoiceEntity? origInvoice,
|
||||||
Function(BuildContext, [EntityAction])? onSavePressed,
|
Function(BuildContext, [EntityAction?])? onSavePressed,
|
||||||
Function(List<InvoiceItemEntity>, String, String)? onItemsAdded,
|
Function(List<InvoiceItemEntity>, String?, String?)? onItemsAdded,
|
||||||
bool? isSaving,
|
bool? isSaving,
|
||||||
Function(BuildContext)? onCancelPressed,
|
Function(BuildContext)? onCancelPressed,
|
||||||
Function(BuildContext, List<MultipartFile>, bool?)? onUploadDocuments,
|
Function(BuildContext, List<MultipartFile>, bool?)? onUploadDocuments,
|
||||||
|
|
@ -116,7 +116,8 @@ class PurchaseOrderEditVM extends AbstractInvoiceEditVM {
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
UpdateCurrentRoute(PurchaseOrderViewScreen.route));
|
UpdateCurrentRoute(PurchaseOrderViewScreen.route));
|
||||||
if (purchaseOrder.isNew) {
|
if (purchaseOrder.isNew) {
|
||||||
navigator!.pushReplacementNamed(PurchaseOrderViewScreen.route);
|
navigator!
|
||||||
|
.pushReplacementNamed(PurchaseOrderViewScreen.route);
|
||||||
} else {
|
} else {
|
||||||
navigator!.pop(savedPurchaseOrder);
|
navigator!.pop(savedPurchaseOrder);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,9 @@ class QuoteEditDetailsVM extends EntityEditDetailsVM {
|
||||||
clientMap: state.clientState.map,
|
clientMap: state.clientState.map,
|
||||||
clientList: state.clientState.list,
|
clientList: state.clientState.list,
|
||||||
onClientChanged: (context, quote, client) {
|
onClientChanged: (context, quote, client) {
|
||||||
store.dispatch(UpdateQuote(quote.applyClient(state, client)));
|
if (client != null) {
|
||||||
|
store.dispatch(UpdateQuote(quote.applyClient(state, client)));
|
||||||
|
}
|
||||||
store.dispatch(UpdateQuoteClient(client: client));
|
store.dispatch(UpdateQuoteClient(client: client));
|
||||||
},
|
},
|
||||||
onAddClientPressed: (context, completer) {
|
onAddClientPressed: (context, completer) {
|
||||||
|
|
|
||||||
|
|
@ -52,8 +52,8 @@ class QuoteEditVM extends AbstractInvoiceEditVM {
|
||||||
InvoiceEntity? invoice,
|
InvoiceEntity? invoice,
|
||||||
int? invoiceItemIndex,
|
int? invoiceItemIndex,
|
||||||
InvoiceEntity? origInvoice,
|
InvoiceEntity? origInvoice,
|
||||||
Function(BuildContext, [EntityAction])? onSavePressed,
|
Function(BuildContext, [EntityAction?])? onSavePressed,
|
||||||
Function(List<InvoiceItemEntity>, String, String)? onItemsAdded,
|
Function(List<InvoiceItemEntity>, String?, String?)? onItemsAdded,
|
||||||
bool? isSaving,
|
bool? isSaving,
|
||||||
Function(BuildContext)? onCancelPressed,
|
Function(BuildContext)? onCancelPressed,
|
||||||
Function(BuildContext, List<MultipartFile>, bool?)? onUploadDocument,
|
Function(BuildContext, List<MultipartFile>, bool?)? onUploadDocument,
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ class RecurringExpenseEditVM extends AbstractExpenseEditVM {
|
||||||
..future.then<Null>(() {
|
..future.then<Null>(() {
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
UpdateCurrentRoute(RecurringExpenseEditScreen.route));
|
UpdateCurrentRoute(RecurringExpenseEditScreen.route));
|
||||||
} as FutureOr<_> Function(Null)));
|
} as FutureOr<Null> Function(Null)));
|
||||||
completer.future.then((SelectableEntity client) {
|
completer.future.then((SelectableEntity client) {
|
||||||
store.dispatch(UpdateCurrentRoute(RecurringExpenseEditScreen.route));
|
store.dispatch(UpdateCurrentRoute(RecurringExpenseEditScreen.route));
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -49,8 +49,8 @@ class RecurringExpenseViewScreen extends StatelessWidget {
|
||||||
|
|
||||||
class RecurringExpenseViewVM extends AbstractExpenseViewVM {
|
class RecurringExpenseViewVM extends AbstractExpenseViewVM {
|
||||||
RecurringExpenseViewVM({
|
RecurringExpenseViewVM({
|
||||||
|
required ExpenseEntity expense,
|
||||||
AppState? state,
|
AppState? state,
|
||||||
ExpenseEntity? expense,
|
|
||||||
CompanyEntity? company,
|
CompanyEntity? company,
|
||||||
Function(BuildContext, EntityAction)? onEntityAction,
|
Function(BuildContext, EntityAction)? onEntityAction,
|
||||||
Function(BuildContext)? onRefreshed,
|
Function(BuildContext)? onRefreshed,
|
||||||
|
|
|
||||||
|
|
@ -92,8 +92,10 @@ class RecurringInvoiceEditDetailsVM extends EntityEditDetailsVM {
|
||||||
clientMap: state.clientState.map,
|
clientMap: state.clientState.map,
|
||||||
clientList: state.clientState.list,
|
clientList: state.clientState.list,
|
||||||
onClientChanged: (context, invoice, client) {
|
onClientChanged: (context, invoice, client) {
|
||||||
store.dispatch(
|
if (client != null) {
|
||||||
UpdateRecurringInvoice(invoice.applyClient(state, client)));
|
store.dispatch(
|
||||||
|
UpdateRecurringInvoice(invoice.applyClient(state, client)));
|
||||||
|
}
|
||||||
store.dispatch(UpdateRecurringInvoiceClient(client: client));
|
store.dispatch(UpdateRecurringInvoiceClient(client: client));
|
||||||
},
|
},
|
||||||
onAddClientPressed: (context, completer) {
|
onAddClientPressed: (context, completer) {
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ class RecurringInvoiceEditVM extends AbstractInvoiceEditVM {
|
||||||
int? invoiceItemIndex,
|
int? invoiceItemIndex,
|
||||||
InvoiceEntity? origInvoice,
|
InvoiceEntity? origInvoice,
|
||||||
Function(BuildContext, [EntityAction?])? onSavePressed,
|
Function(BuildContext, [EntityAction?])? onSavePressed,
|
||||||
Function(List<InvoiceItemEntity>, String, String)? onItemsAdded,
|
Function(List<InvoiceItemEntity>, String?, String?)? onItemsAdded,
|
||||||
bool? isSaving,
|
bool? isSaving,
|
||||||
Function(BuildContext)? onCancelPressed,
|
Function(BuildContext)? onCancelPressed,
|
||||||
Function(BuildContext, List<MultipartFile>, bool)? onUploadDocuments,
|
Function(BuildContext, List<MultipartFile>, bool)? onUploadDocuments,
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ ReportResult documentReport(
|
||||||
BuiltMap<String?, UserEntity?> userMap,
|
BuiltMap<String?, UserEntity?> userMap,
|
||||||
) {
|
) {
|
||||||
final List<List<ReportElement>> data = [];
|
final List<List<ReportElement>> data = [];
|
||||||
final List<BaseEntity?> entities = [];
|
final List<BaseEntity> entities = [];
|
||||||
BuiltList<DocumentReportFields> columns;
|
BuiltList<DocumentReportFields> columns;
|
||||||
|
|
||||||
final localization =
|
final localization =
|
||||||
|
|
@ -144,13 +144,13 @@ ReportResult documentReport(
|
||||||
|
|
||||||
if (!skip) {
|
if (!skip) {
|
||||||
data.add(row);
|
data.add(row);
|
||||||
entities.add(document);
|
entities.add(document!);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
final selectedColumns = columns.map((item) => EnumUtils.parse(item)).toList();
|
final selectedColumns = columns.map((item) => EnumUtils.parse(item)).toList();
|
||||||
data.sort((rowA, rowB) =>
|
data.sort((rowA, rowB) => sortReportTableRows(
|
||||||
sortReportTableRows(rowA, rowB, documentReportSettings, selectedColumns)!);
|
rowA, rowB, documentReportSettings, selectedColumns)!);
|
||||||
|
|
||||||
return ReportResult(
|
return ReportResult(
|
||||||
allColumns:
|
allColumns:
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
// Flutter imports:
|
// Flutter imports:
|
||||||
|
import 'package:charts_flutter/flutter.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
// Package imports:
|
// Package imports:
|
||||||
|
|
@ -71,8 +72,8 @@ class ReportCharts extends StatelessWidget {
|
||||||
data: viewModel.groupTotals.rows!.map((key) {
|
data: viewModel.groupTotals.rows!.map((key) {
|
||||||
return {
|
return {
|
||||||
'name': key,
|
'name': key,
|
||||||
'value': viewModel.groupTotals.totals![key]!
|
'value':
|
||||||
[reportState.chart]
|
viewModel.groupTotals.totals![key]![reportState.chart]
|
||||||
};
|
};
|
||||||
}).toList()) as Series<dynamic, String>
|
}).toList()) as Series<dynamic, String>
|
||||||
],
|
],
|
||||||
|
|
@ -98,8 +99,8 @@ class ReportCharts extends StatelessWidget {
|
||||||
data: keys.map((key) {
|
data: keys.map((key) {
|
||||||
return {
|
return {
|
||||||
'name': key,
|
'name': key,
|
||||||
'value': viewModel.groupTotals.totals![key]!
|
'value':
|
||||||
[reportState.chart]
|
viewModel.groupTotals.totals![key]![reportState.chart]
|
||||||
};
|
};
|
||||||
}).toList()) as Series<dynamic, DateTime>
|
}).toList()) as Series<dynamic, DateTime>
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
// Flutter imports:
|
// Flutter imports:
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:collection/collection.dart' show IterableNullableExtension;
|
import 'package:collection/collection.dart' show IterableNullableExtension;
|
||||||
import 'package:flutter/material.dart' hide DataRow, DataCell, DataColumn;
|
import 'package:flutter/material.dart' hide DataRow, DataCell, DataColumn;
|
||||||
import 'package:flutter/material.dart' as mt;
|
import 'package:flutter/material.dart' as mt;
|
||||||
|
|
@ -961,7 +963,7 @@ class ReportResult {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool matchDateTime({
|
static bool matchDateTime({
|
||||||
String? filter,
|
required String filter,
|
||||||
required String value,
|
required String value,
|
||||||
required UserCompanyEntity userCompany,
|
required UserCompanyEntity userCompany,
|
||||||
required ReportsUIState reportsUIState,
|
required ReportsUIState reportsUIState,
|
||||||
|
|
@ -1165,7 +1167,7 @@ class ReportResult {
|
||||||
showBlank: true,
|
showBlank: true,
|
||||||
blankValue: null,
|
blankValue: null,
|
||||||
value: (reportState.filters[column] ?? '').isNotEmpty
|
value: (reportState.filters[column] ?? '').isNotEmpty
|
||||||
? DateRange.valueOf(reportState.filters[column])
|
? DateRange.valueOf(reportState.filters[column]!)
|
||||||
: null,
|
: null,
|
||||||
onChanged: (dynamic value) {
|
onChanged: (dynamic value) {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
|
|
@ -1213,7 +1215,7 @@ class ReportResult {
|
||||||
focusNode: textEditingFocusNodes![column],
|
focusNode: textEditingFocusNodes![column],
|
||||||
optionsBuilder: (TextEditingValue textEditingValue) {
|
optionsBuilder: (TextEditingValue textEditingValue) {
|
||||||
final filter = textEditingValue.text.toLowerCase();
|
final filter = textEditingValue.text.toLowerCase();
|
||||||
final index = columns.indexOf(column);
|
final index = columns.indexOf(column!);
|
||||||
final options = data
|
final options = data
|
||||||
.where((row) =>
|
.where((row) =>
|
||||||
row[index]
|
row[index]
|
||||||
|
|
@ -1327,7 +1329,7 @@ class ReportResult {
|
||||||
final row = data[index - 1];
|
final row = data[index - 1];
|
||||||
final cells = <DataCell>[];
|
final cells = <DataCell>[];
|
||||||
for (var j = 0; j < row.length; j++) {
|
for (var j = 0; j < row.length; j++) {
|
||||||
final index = columns.indexOf(sorted[j]);
|
final index = columns.indexOf(sorted[j]!);
|
||||||
final cell = row[index];
|
final cell = row[index];
|
||||||
final column = sorted[j];
|
final column = sorted[j];
|
||||||
cells.add(
|
cells.add(
|
||||||
|
|
@ -1534,13 +1536,14 @@ class ReportResult {
|
||||||
totals[currencyId] = {'count': 0};
|
totals[currencyId] = {'count': 0};
|
||||||
}
|
}
|
||||||
if (!countedRow) {
|
if (!countedRow) {
|
||||||
totals[currencyId]!['count']++;
|
totals[currencyId]!['count'] = totals[currencyId]!['count']! + 1;
|
||||||
countedRow = true;
|
countedRow = true;
|
||||||
}
|
}
|
||||||
if (!totals[currencyId]!.containsKey(column)) {
|
if (!totals[currencyId]!.containsKey(column)) {
|
||||||
totals[currencyId]![column] = 0;
|
totals[currencyId]![column] = 0;
|
||||||
}
|
}
|
||||||
totals[currencyId]![column] += cell.doubleValue!;
|
totals[currencyId]![column] =
|
||||||
|
totals[currencyId]![column]! + cell.doubleValue!;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ class TransactionViewVM {
|
||||||
transactionIds = [state.transactionUIState.selectedId];
|
transactionIds = [state.transactionUIState.selectedId];
|
||||||
}
|
}
|
||||||
|
|
||||||
transactionIds.forEach((transactionId) {
|
transactionIds.forEach((String transactionId) {
|
||||||
transactions.add(state.transactionState.map[transactionId] ??
|
transactions.add(state.transactionState.map[transactionId] ??
|
||||||
TransactionEntity(id: transactionId));
|
TransactionEntity(id: transactionId));
|
||||||
} as void Function(String?));
|
} as void Function(String?));
|
||||||
|
|
@ -118,14 +118,14 @@ class TransactionViewVM {
|
||||||
ConvertTransactionsToExpensesRequest(
|
ConvertTransactionsToExpensesRequest(
|
||||||
snackBarCompleter<Null>(
|
snackBarCompleter<Null>(
|
||||||
context, AppLocalization.of(context)!.convertedTransaction)
|
context, AppLocalization.of(context)!.convertedTransaction)
|
||||||
..future.then((value) {
|
..future.then<Null>(() {
|
||||||
if (state.transactionListState.isInMultiselect()) {
|
if (state.transactionListState.isInMultiselect()) {
|
||||||
store.dispatch(ClearTransactionMultiselect());
|
store.dispatch(ClearTransactionMultiselect());
|
||||||
if (store.state.prefState.isPreviewVisible) {
|
if (store.state.prefState.isPreviewVisible) {
|
||||||
store.dispatch(TogglePreviewSidebar());
|
store.dispatch(TogglePreviewSidebar());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} as FutureOr<_> Function(Null)),
|
} as FutureOr<Null> Function(Null)),
|
||||||
transactionIds,
|
transactionIds,
|
||||||
vendorId,
|
vendorId,
|
||||||
categoryId,
|
categoryId,
|
||||||
|
|
|
||||||
|
|
@ -502,6 +502,7 @@ class _ExampleEditorState extends State<ExampleEditor> {
|
||||||
onCutPressed: _cut,
|
onCutPressed: _cut,
|
||||||
onCopyPressed: _copy,
|
onCopyPressed: _copy,
|
||||||
onPastePressed: _paste,
|
onPastePressed: _paste,
|
||||||
|
focalPoint: _overlayController.toolbarTopAnchor!,
|
||||||
),
|
),
|
||||||
overlayController: _overlayController,
|
overlayController: _overlayController,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ class WebUtils {
|
||||||
final loginRequest = PopupRequest()..scopes = ['user.read'];
|
final loginRequest = PopupRequest()..scopes = ['user.read'];
|
||||||
|
|
||||||
publicClientApp.loginPopup(loginRequest).then((result) {
|
publicClientApp.loginPopup(loginRequest).then((result) {
|
||||||
succesCallback(result?.idToken, result?.accessToken);
|
succesCallback(result?.idToken ?? '', result?.accessToken ?? '');
|
||||||
}).catchError((dynamic error) {
|
}).catchError((dynamic error) {
|
||||||
failureCallback(error);
|
failureCallback(error);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -243,7 +243,7 @@ class ContactForm extends StatefulWidget {
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final ContactEntity contact;
|
final ContactEntity contact;
|
||||||
final Function(GlobalKey<ContactFormState>?) onRemovePressed;
|
final Function(GlobalKey<ContactFormState>) onRemovePressed;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ContactFormState createState() => ContactFormState();
|
ContactFormState createState() => ContactFormState();
|
||||||
|
|
@ -274,7 +274,8 @@ class ContactFormState extends State<ContactForm> {
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(top: 12.0),
|
padding: const EdgeInsets.only(top: 12.0),
|
||||||
child: TextButton(
|
child: TextButton(
|
||||||
onPressed: () => widget.onRemovePressed(widget.key as GlobalKey<ContactFormState>?),
|
onPressed: () => widget
|
||||||
|
.onRemovePressed(widget.key as GlobalKey<ContactFormState>),
|
||||||
child: Text(
|
child: Text(
|
||||||
'Delete',
|
'Delete',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue