Null safety
This commit is contained in:
parent
f5e6fe9cfe
commit
3b435fd70b
|
|
@ -1,4 +1,5 @@
|
||||||
// Dart imports:
|
// Dart imports:
|
||||||
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:core';
|
import 'dart:core';
|
||||||
|
|
||||||
|
|
@ -32,7 +33,8 @@ class QuoteRepository {
|
||||||
|
|
||||||
final InvoiceItemResponse quoteResponse = await (compute<dynamic, dynamic>(
|
final InvoiceItemResponse quoteResponse = await (compute<dynamic, dynamic>(
|
||||||
SerializationUtils.deserializeWith,
|
SerializationUtils.deserializeWith,
|
||||||
<dynamic>[InvoiceItemResponse.serializer, response]) as FutureOr<InvoiceItemResponse>);
|
<dynamic>[InvoiceItemResponse.serializer, response])
|
||||||
|
as FutureOr<InvoiceItemResponse>);
|
||||||
|
|
||||||
return quoteResponse.data;
|
return quoteResponse.data;
|
||||||
}
|
}
|
||||||
|
|
@ -50,7 +52,8 @@ class QuoteRepository {
|
||||||
|
|
||||||
final InvoiceListResponse quoteResponse = await (compute<dynamic, dynamic>(
|
final InvoiceListResponse quoteResponse = await (compute<dynamic, dynamic>(
|
||||||
SerializationUtils.deserializeWith,
|
SerializationUtils.deserializeWith,
|
||||||
<dynamic>[InvoiceListResponse.serializer, response]) as FutureOr<InvoiceListResponse>);
|
<dynamic>[InvoiceListResponse.serializer, response])
|
||||||
|
as FutureOr<InvoiceListResponse>);
|
||||||
|
|
||||||
return quoteResponse.data;
|
return quoteResponse.data;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ class RecurringInvoiceRepository {
|
||||||
|
|
||||||
Future<List<InvoiceEntity>> bulkAction(
|
Future<List<InvoiceEntity>> bulkAction(
|
||||||
Credentials credentials, List<String> ids, EntityAction action,
|
Credentials credentials, List<String> ids, EntityAction action,
|
||||||
{Map<String, Object?>? data}) async {
|
{Map<String, Object>? data}) async {
|
||||||
if (ids.length > kMaxEntitiesPerBulkAction && action.applyMaxLimit) {
|
if (ids.length > kMaxEntitiesPerBulkAction && action.applyMaxLimit) {
|
||||||
ids = ids.sublist(0, kMaxEntitiesPerBulkAction);
|
ids = ids.sublist(0, kMaxEntitiesPerBulkAction);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
// Dart imports:
|
// Dart imports:
|
||||||
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:core';
|
import 'dart:core';
|
||||||
|
|
||||||
|
|
@ -30,7 +31,8 @@ class TaskRepository {
|
||||||
|
|
||||||
final TaskItemResponse taskResponse = await (compute<dynamic, dynamic>(
|
final TaskItemResponse taskResponse = await (compute<dynamic, dynamic>(
|
||||||
SerializationUtils.deserializeWith,
|
SerializationUtils.deserializeWith,
|
||||||
<dynamic>[TaskItemResponse.serializer, response]) as FutureOr<TaskItemResponse>);
|
<dynamic>[TaskItemResponse.serializer, response])
|
||||||
|
as FutureOr<TaskItemResponse>);
|
||||||
|
|
||||||
return taskResponse.data;
|
return taskResponse.data;
|
||||||
}
|
}
|
||||||
|
|
@ -50,7 +52,8 @@ class TaskRepository {
|
||||||
|
|
||||||
final TaskListResponse taskResponse = await (compute<dynamic, dynamic>(
|
final TaskListResponse taskResponse = await (compute<dynamic, dynamic>(
|
||||||
SerializationUtils.deserializeWith,
|
SerializationUtils.deserializeWith,
|
||||||
<dynamic>[TaskListResponse.serializer, response]) as FutureOr<TaskListResponse>);
|
<dynamic>[TaskListResponse.serializer, response])
|
||||||
|
as FutureOr<TaskListResponse>);
|
||||||
|
|
||||||
return taskResponse.data;
|
return taskResponse.data;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
// Dart imports:
|
// Dart imports:
|
||||||
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:core';
|
import 'dart:core';
|
||||||
|
|
||||||
|
|
@ -32,7 +33,8 @@ class VendorRepository {
|
||||||
|
|
||||||
final VendorItemResponse vendorResponse = await (compute<dynamic, dynamic>(
|
final VendorItemResponse vendorResponse = await (compute<dynamic, dynamic>(
|
||||||
SerializationUtils.deserializeWith,
|
SerializationUtils.deserializeWith,
|
||||||
<dynamic>[VendorItemResponse.serializer, response]) as FutureOr<VendorItemResponse>);
|
<dynamic>[VendorItemResponse.serializer, response])
|
||||||
|
as FutureOr<VendorItemResponse>);
|
||||||
|
|
||||||
return vendorResponse.data;
|
return vendorResponse.data;
|
||||||
}
|
}
|
||||||
|
|
@ -46,7 +48,8 @@ class VendorRepository {
|
||||||
|
|
||||||
final VendorListResponse vendorResponse = await (compute<dynamic, dynamic>(
|
final VendorListResponse vendorResponse = await (compute<dynamic, dynamic>(
|
||||||
SerializationUtils.deserializeWith,
|
SerializationUtils.deserializeWith,
|
||||||
<dynamic>[VendorListResponse.serializer, response]) as FutureOr<VendorListResponse>);
|
<dynamic>[VendorListResponse.serializer, response])
|
||||||
|
as FutureOr<VendorListResponse>);
|
||||||
|
|
||||||
return vendorResponse.data;
|
return vendorResponse.data;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -234,10 +234,10 @@ Middleware<AppState> _createLoadState(
|
||||||
store.dispatch(LoadStateSuccess(appState));
|
store.dispatch(LoadStateSuccess(appState));
|
||||||
store.dispatch(RefreshData(
|
store.dispatch(RefreshData(
|
||||||
completer: Completer<Null>()
|
completer: Completer<Null>()
|
||||||
..future.then((value) {
|
..future.then<Null>(() {
|
||||||
AppBuilder.of(navigatorKey.currentContext!)!.rebuild();
|
AppBuilder.of(navigatorKey.currentContext!)!.rebuild();
|
||||||
store.dispatch(UpdatedSetting());
|
store.dispatch(UpdatedSetting());
|
||||||
} as FutureOr<_> Function(Null))));
|
} as FutureOr<Null> Function(Null))));
|
||||||
|
|
||||||
if (uiState!.currentRoute != LoginScreen.route &&
|
if (uiState!.currentRoute != LoginScreen.route &&
|
||||||
uiState!.currentRoute.isNotEmpty) {
|
uiState!.currentRoute.isNotEmpty) {
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,9 @@ abstract class AppState implements Built<AppState, AppStateBuilder> {
|
||||||
.map((index) => UserCompanyState(reportErrors))
|
.map((index) => UserCompanyState(reportErrors))
|
||||||
.toList()),
|
.toList()),
|
||||||
uiState: UIState(
|
uiState: UIState(
|
||||||
currentRoute: currentRoute, sortFields: prefState?.sortFields),
|
currentRoute: currentRoute,
|
||||||
|
sortFields: prefState?.sortFields ??
|
||||||
|
BuiltMap<EntityType, PrefStateSortField>()),
|
||||||
prefState: prefState ?? PrefState(),
|
prefState: prefState ?? PrefState(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -192,7 +194,8 @@ abstract class AppState implements Built<AppState, AppStateBuilder> {
|
||||||
return color.isNotEmpty;
|
return color.isNotEmpty;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get showReviewApp => !prefState.hideReviewApp && company!.daysActive > 60;
|
bool get showReviewApp =>
|
||||||
|
!prefState.hideReviewApp && company!.daysActive > 60;
|
||||||
|
|
||||||
bool get showOneYearReviewApp =>
|
bool get showOneYearReviewApp =>
|
||||||
!prefState.hideOneYearReviewApp && company!.daysActive > 365;
|
!prefState.hideOneYearReviewApp && company!.daysActive > 365;
|
||||||
|
|
@ -251,7 +254,8 @@ abstract class AppState implements Built<AppState, AppStateBuilder> {
|
||||||
List<HistoryRecord> get unfilteredHistoryList =>
|
List<HistoryRecord> get unfilteredHistoryList =>
|
||||||
prefState.companyPrefs[company!.id]!.historyList.toList();
|
prefState.companyPrefs[company!.id]!.historyList.toList();
|
||||||
|
|
||||||
bool? shouldSelectEntity({EntityType? entityType, List<String?>? entityList}) {
|
bool? shouldSelectEntity(
|
||||||
|
{EntityType? entityType, List<String?>? entityList}) {
|
||||||
final entityUIState = getUIState(entityType);
|
final entityUIState = getUIState(entityType);
|
||||||
|
|
||||||
if (prefState.isMobile ||
|
if (prefState.isMobile ||
|
||||||
|
|
@ -962,8 +966,8 @@ abstract class AppState implements Built<AppState, AppStateBuilder> {
|
||||||
: timeago.format(convertTimestampToDate(
|
: timeago.format(convertTimestampToDate(
|
||||||
(userCompanyState.lastUpdated / 1000).round()));
|
(userCompanyState.lastUpdated / 1000).round()));
|
||||||
|
|
||||||
final staticUpdated =
|
final staticUpdated = staticState.updatedAt == null ||
|
||||||
staticState.updatedAt == null || staticState.updatedAt == 0
|
staticState.updatedAt == 0
|
||||||
? 'Blank'
|
? 'Blank'
|
||||||
: timeago.format(
|
: timeago.format(
|
||||||
convertTimestampToDate((staticState.updatedAt! / 1000).round()));
|
convertTimestampToDate((staticState.updatedAt! / 1000).round()));
|
||||||
|
|
|
||||||
|
|
@ -379,7 +379,7 @@ Middleware<AppState> _createCompany(AuthRepository repository) {
|
||||||
store.dispatch(RefreshData(
|
store.dispatch(RefreshData(
|
||||||
allCompanies: true,
|
allCompanies: true,
|
||||||
completer: Completer<Null>()
|
completer: Completer<Null>()
|
||||||
..future.then<Null>((_) {
|
..future.then<Null>(() {
|
||||||
store.dispatch(SelectCompany(companyIndex: state.companies.length));
|
store.dispatch(SelectCompany(companyIndex: state.companies.length));
|
||||||
store.dispatch(ViewDashboard(force: true));
|
store.dispatch(ViewDashboard(force: true));
|
||||||
|
|
||||||
|
|
@ -459,9 +459,9 @@ Middleware<AppState> _purgeData(AuthRepository repository) {
|
||||||
store.dispatch(RefreshData(
|
store.dispatch(RefreshData(
|
||||||
clearData: true,
|
clearData: true,
|
||||||
completer: Completer<Null>()
|
completer: Completer<Null>()
|
||||||
..future.then((value) {
|
..future.then<Null>(() {
|
||||||
action.completer.complete(null);
|
action.completer.complete(null);
|
||||||
} as FutureOr<_> Function(Null))));
|
} as FutureOr<Null> Function(Null))));
|
||||||
}).catchError((Object error) {
|
}).catchError((Object error) {
|
||||||
store.dispatch(PurgeDataFailure(error));
|
store.dispatch(PurgeDataFailure(error));
|
||||||
action.completer.completeError(error);
|
action.completer.completeError(error);
|
||||||
|
|
|
||||||
|
|
@ -309,9 +309,9 @@ void handleCompanyGatewayAction(BuildContext? context,
|
||||||
case EntityAction.disconnect:
|
case EntityAction.disconnect:
|
||||||
final completer =
|
final completer =
|
||||||
snackBarCompleter<Null>(context, localization!.disconnectedGateway);
|
snackBarCompleter<Null>(context, localization!.disconnectedGateway);
|
||||||
completer.future.then((value) {
|
completer.future.then<Null>(() {
|
||||||
store.dispatch(RefreshData());
|
store.dispatch(RefreshData());
|
||||||
} as FutureOr<_> Function(Null));
|
} as FutureOr<Null> Function(Null));
|
||||||
confirmCallback(
|
confirmCallback(
|
||||||
context: context,
|
context: context,
|
||||||
callback: (_) {
|
callback: (_) {
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ DashboardUISettings dashboardSettingsReducer(
|
||||||
} else if (action.includeTaxes != null) {
|
} else if (action.includeTaxes != null) {
|
||||||
return state.rebuild((b) => b..includeTaxes = action.includeTaxes);
|
return state.rebuild((b) => b..includeTaxes = action.includeTaxes);
|
||||||
} else if (action.offset != null) {
|
} else if (action.offset != null) {
|
||||||
return state.rebuild((b) => b..offset += action.offset!);
|
return state.rebuild((b) => b..offset = state.offset + action.offset!);
|
||||||
} else if (action.currencyId != null) {
|
} else if (action.currencyId != null) {
|
||||||
return state.rebuild((b) => b..currencyId = action.currencyId);
|
return state.rebuild((b) => b..currencyId = action.currencyId);
|
||||||
} else if (action.groupBy != null) {
|
} else if (action.groupBy != null) {
|
||||||
|
|
|
||||||
|
|
@ -150,17 +150,18 @@ List<ChartDataGroup> _chartInvoices({
|
||||||
outstandingData.entityMap[date] = [];
|
outstandingData.entityMap[date] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
totals[STATUS_ACTIVE]![date] += amount;
|
totals[STATUS_ACTIVE]![date] = totals[STATUS_ACTIVE]![date]! + amount;
|
||||||
totals[STATUS_OUTSTANDING]![date] += balance;
|
totals[STATUS_OUTSTANDING]![date] =
|
||||||
|
totals[STATUS_OUTSTANDING]![date]! + balance;
|
||||||
|
|
||||||
activeData.periodTotal += amount;
|
activeData.periodTotal += amount;
|
||||||
outstandingData.periodTotal += balance;
|
outstandingData.periodTotal += balance;
|
||||||
|
|
||||||
counts[STATUS_ACTIVE]++;
|
counts[STATUS_ACTIVE] = counts[STATUS_ACTIVE]! + 1;
|
||||||
activeData.entityMap[date]!.add(invoice.id);
|
activeData.entityMap[date]!.add(invoice.id);
|
||||||
|
|
||||||
if (invoice.balance > 0) {
|
if (invoice.balance > 0) {
|
||||||
counts[STATUS_OUTSTANDING]++;
|
counts[STATUS_OUTSTANDING] = counts[STATUS_OUTSTANDING]! + 1;
|
||||||
outstandingData.entityMap[date]!.add(invoice.id);
|
outstandingData.entityMap[date]!.add(invoice.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -275,7 +276,10 @@ List<ChartDataGroup> chartQuotes({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!quote.isSent || quote.isDeleted! || client.isDeleted! || date.isEmpty) {
|
if (!quote.isSent ||
|
||||||
|
quote.isDeleted! ||
|
||||||
|
client.isDeleted! ||
|
||||||
|
date.isEmpty) {
|
||||||
// skip it
|
// skip it
|
||||||
} else if (!settings.matchesCurrency(client.currencyId)) {
|
} else if (!settings.matchesCurrency(client.currencyId)) {
|
||||||
// skip it
|
// skip it
|
||||||
|
|
@ -312,18 +316,20 @@ List<ChartDataGroup> chartQuotes({
|
||||||
unapprovedData.entityMap[date] = [];
|
unapprovedData.entityMap[date] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
totals[STATUS_ACTIVE]![date] += amount;
|
totals[STATUS_ACTIVE]![date] = totals[STATUS_ACTIVE]![date]! + amount;
|
||||||
counts[STATUS_ACTIVE]++;
|
counts[STATUS_ACTIVE] = counts[STATUS_ACTIVE]! + 1;
|
||||||
activeData.entityMap[date]!.add(quote.id);
|
activeData.entityMap[date]!.add(quote.id);
|
||||||
|
|
||||||
if (quote.isApproved) {
|
if (quote.isApproved) {
|
||||||
totals[STATUS_APPROVED]![date] += amount;
|
totals[STATUS_APPROVED]![date] =
|
||||||
counts[STATUS_APPROVED]++;
|
totals[STATUS_APPROVED]![date]! + amount;
|
||||||
|
counts[STATUS_APPROVED] = counts[STATUS_APPROVED]! + 1;
|
||||||
approvedData.entityMap[date]!.add(quote.id);
|
approvedData.entityMap[date]!.add(quote.id);
|
||||||
approvedData.periodTotal += amount;
|
approvedData.periodTotal += amount;
|
||||||
} else {
|
} else {
|
||||||
totals[STATUS_UNAPPROVED]![date] += amount;
|
totals[STATUS_UNAPPROVED]![date] =
|
||||||
counts[STATUS_UNAPPROVED]++;
|
totals[STATUS_UNAPPROVED]![date]! + amount;
|
||||||
|
counts[STATUS_UNAPPROVED] = counts[STATUS_UNAPPROVED]! + 1;
|
||||||
unapprovedData.entityMap[date]!.add(quote.id);
|
unapprovedData.entityMap[date]!.add(quote.id);
|
||||||
unapprovedData.periodTotal += amount;
|
unapprovedData.periodTotal += amount;
|
||||||
}
|
}
|
||||||
|
|
@ -928,7 +934,8 @@ List<ChartDataGroup> chartExpenses(
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
var memoizedChartExpenses = memo5((BuiltMap<String?, CurrencyEntity?> currencyMap,
|
var memoizedChartExpenses = memo5(
|
||||||
|
(BuiltMap<String?, CurrencyEntity?> currencyMap,
|
||||||
CompanyEntity? company,
|
CompanyEntity? company,
|
||||||
DashboardUISettings settings,
|
DashboardUISettings settings,
|
||||||
BuiltMap<String?, InvoiceEntity?> invoiceMap,
|
BuiltMap<String?, InvoiceEntity?> invoiceMap,
|
||||||
|
|
|
||||||
|
|
@ -189,9 +189,12 @@ class InvoiceOverview extends StatelessWidget {
|
||||||
RecurringInvoiceFields.remainingCycles: invoice.remainingCycles == -1
|
RecurringInvoiceFields.remainingCycles: invoice.remainingCycles == -1
|
||||||
? localization.endless
|
? localization.endless
|
||||||
: '${invoice.remainingCycles}',
|
: '${invoice.remainingCycles}',
|
||||||
RecurringInvoiceFields.autoBill: localization.lookup(invoice.autoBill)! +
|
RecurringInvoiceFields.autoBill:
|
||||||
([SettingsEntity.AUTO_BILL_OPT_IN, SettingsEntity.AUTO_BILL_OPT_OUT]
|
localization.lookup(invoice.autoBill)! +
|
||||||
.contains(invoice.autoBill)
|
([
|
||||||
|
SettingsEntity.AUTO_BILL_OPT_IN,
|
||||||
|
SettingsEntity.AUTO_BILL_OPT_OUT
|
||||||
|
].contains(invoice.autoBill)
|
||||||
? (' - ' +
|
? (' - ' +
|
||||||
(invoice.autoBillEnabled
|
(invoice.autoBillEnabled
|
||||||
? localization.yes
|
? localization.yes
|
||||||
|
|
@ -320,12 +323,12 @@ class InvoiceOverview extends StatelessWidget {
|
||||||
paymentMap.entries.forEach((entry) {
|
paymentMap.entries.forEach((entry) {
|
||||||
final payment = entry.value!;
|
final payment = entry.value!;
|
||||||
final paymentable = entry.key;
|
final paymentable = entry.key;
|
||||||
String? amount = formatNumber(
|
String amount = formatNumber(
|
||||||
paymentable.amount,
|
paymentable.amount,
|
||||||
context,
|
context,
|
||||||
clientId: invoice.isPurchaseOrder ? null : client!.id,
|
clientId: invoice.isPurchaseOrder ? null : client!.id,
|
||||||
vendorId: invoice.isPurchaseOrder ? invoice.vendorId : null,
|
vendorId: invoice.isPurchaseOrder ? invoice.vendorId : null,
|
||||||
);
|
)!;
|
||||||
if (paymentable.amount != payment.amount) {
|
if (paymentable.amount != payment.amount) {
|
||||||
amount += '/' +
|
amount += '/' +
|
||||||
formatNumber(
|
formatNumber(
|
||||||
|
|
@ -350,12 +353,12 @@ class InvoiceOverview extends StatelessWidget {
|
||||||
creditMap.entries.forEach((entry) {
|
creditMap.entries.forEach((entry) {
|
||||||
final credit = entry.value!;
|
final credit = entry.value!;
|
||||||
final paymentable = entry.key;
|
final paymentable = entry.key;
|
||||||
String? amount = formatNumber(
|
String amount = formatNumber(
|
||||||
paymentable.amount,
|
paymentable.amount,
|
||||||
context,
|
context,
|
||||||
clientId: invoice.isPurchaseOrder ? null : client!.id,
|
clientId: invoice.isPurchaseOrder ? null : client!.id,
|
||||||
vendorId: invoice.isPurchaseOrder ? invoice.vendorId : null,
|
vendorId: invoice.isPurchaseOrder ? invoice.vendorId : null,
|
||||||
);
|
)!;
|
||||||
if (paymentable.amount != credit.amount) {
|
if (paymentable.amount != credit.amount) {
|
||||||
amount += '/' +
|
amount += '/' +
|
||||||
formatNumber(
|
formatNumber(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue