Null safety

This commit is contained in:
Hillel Coren 2023-09-18 17:32:52 +03:00
parent f5e6fe9cfe
commit 3b435fd70b
11 changed files with 81 additions and 58 deletions

View File

@ -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;
} }

View File

@ -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);
} }

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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) {

View File

@ -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()));

View File

@ -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);

View File

@ -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: (_) {

View File

@ -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) {

View File

@ -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,

View File

@ -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(