diff --git a/lib/ui/dashboard/dashboard_sidebar.dart b/lib/ui/dashboard/dashboard_sidebar.dart index aeb2c7142..8f3af69bf 100644 --- a/lib/ui/dashboard/dashboard_sidebar.dart +++ b/lib/ui/dashboard/dashboard_sidebar.dart @@ -186,7 +186,7 @@ class PaymentSidebar extends StatelessWidget { itemCount: recentPayments.length, itemBuilder: (BuildContext context, int index) { return PaymentListItem( - payment: recentPayments[index], + payment: recentPayments[index]!, showSelected: false, ); }, diff --git a/lib/ui/expense/view/expense_view_overview.dart b/lib/ui/expense/view/expense_view_overview.dart index 97f2d4ba3..08256183b 100644 --- a/lib/ui/expense/view/expense_view_overview.dart +++ b/lib/ui/expense/view/expense_view_overview.dart @@ -189,7 +189,7 @@ class ExpenseOverview extends StatelessWidget { currencyId: expense.currencyId), ), ListDivider(), - if ((expense.privateNotes ?? '').isNotEmpty) ...[ + if (expense.privateNotes.isNotEmpty) ...[ IconMessage(expense.privateNotes, iconData: Icons.lock, copyToClipboard: true), ListDivider(), @@ -223,7 +223,7 @@ class ExpenseOverview extends StatelessWidget { .present(localization.active, localization.archived), ), ..._buildDetailsList(), - if ((expense.publicNotes ?? '').isNotEmpty) ...[ + if (expense.publicNotes.isNotEmpty) ...[ IconMessage(expense.publicNotes, copyToClipboard: true), ListDivider() ], diff --git a/lib/ui/invoice/edit/invoice_edit_desktop.dart b/lib/ui/invoice/edit/invoice_edit_desktop.dart index 76fbc94d8..46fd09992 100644 --- a/lib/ui/invoice/edit/invoice_edit_desktop.dart +++ b/lib/ui/invoice/edit/invoice_edit_desktop.dart @@ -250,9 +250,8 @@ class InvoiceEditDesktopState extends State !item!.isEmpty && item.typeId == InvoiceItemEntity.TYPE_TASK) .length; - final showTasksTable = - (invoice.hasTasks || (company.showTasksTable ?? false)) && - (invoice.isInvoice || invoice.isQuote); + final showTasksTable = (invoice.hasTasks || company.showTasksTable) && + (invoice.isInvoice || invoice.isQuote); final settings = getClientSettings(state, client); final terms = entityType == EntityType.quote @@ -376,7 +375,7 @@ class InvoiceEditDesktopState extends State )) .toList()), DatePicker( - labelText: (invoice.lastSentDate ?? '').isNotEmpty + labelText: invoice.lastSentDate.isNotEmpty ? localization.nextSendDate : localization.startDate, onSelected: (date, _) { diff --git a/lib/ui/invoice/edit/invoice_edit_details.dart b/lib/ui/invoice/edit/invoice_edit_details.dart index a11647b69..1eb2adaae 100644 --- a/lib/ui/invoice/edit/invoice_edit_details.dart +++ b/lib/ui/invoice/edit/invoice_edit_details.dart @@ -223,7 +223,7 @@ class InvoiceEditDetailsState extends State { )) .toList()), DatePicker( - labelText: (invoice.lastSentDate ?? '').isNotEmpty + labelText: invoice.lastSentDate.isNotEmpty ? localization.nextSendDate : localization.startDate, onSelected: (date, _) => viewModel diff --git a/lib/ui/invoice/edit/invoice_edit_items_desktop.dart b/lib/ui/invoice/edit/invoice_edit_items_desktop.dart index e760cbb17..fed3bb1ee 100644 --- a/lib/ui/invoice/edit/invoice_edit_items_desktop.dart +++ b/lib/ui/invoice/edit/invoice_edit_items_desktop.dart @@ -448,10 +448,10 @@ class _InvoiceEditItemsDesktopState extends State { ..._columns .map((column) { if (column == COLUMN_ITEM) { - return Text(item.productKey ?? ''); + return Text(item.productKey); } else if (column == COLUMN_DESCRIPTION) { return Text( - item.notes ?? '', + item.notes, maxLines: 2, // TODO change to 1 overflow: TextOverflow.ellipsis, ); diff --git a/lib/ui/invoice/view/invoice_view_history.dart b/lib/ui/invoice/view/invoice_view_history.dart index 5c96efcf7..51b80d2e4 100644 --- a/lib/ui/invoice/view/invoice_view_history.dart +++ b/lib/ui/invoice/view/invoice_view_history.dart @@ -57,7 +57,7 @@ class _InvoiceViewHistoryState extends State { itemBuilder: (BuildContext context, index) { final activity = activityList[index]; final history = activity.history!; - final activityId = history.activityId ?? ''; + final activityId = history.activityId; final state = viewModel.state!; final client = state.clientState.get(activity.clientId!); diff --git a/lib/ui/invoice/view/invoice_view_overview.dart b/lib/ui/invoice/view/invoice_view_overview.dart index 6dabde957..a65c17b80 100644 --- a/lib/ui/invoice/view/invoice_view_overview.dart +++ b/lib/ui/invoice/view/invoice_view_overview.dart @@ -137,7 +137,7 @@ class InvoiceOverview extends StatelessWidget { ListDivider(), ]); - if ((invoice.privateNotes ?? '').isNotEmpty) { + if (invoice.privateNotes.isNotEmpty) { widgets.addAll([ IconMessage(invoice.privateNotes, iconData: Icons.lock, copyToClipboard: true), @@ -516,7 +516,7 @@ class InvoiceOverview extends StatelessWidget { widgets.add(surchargeRow(localization.partialDue, invoice.partial)); } - if ((invoice.publicNotes ?? '').isNotEmpty) { + if (invoice.publicNotes.isNotEmpty) { widgets.addAll([ ListDivider(), IconMessage(invoice.publicNotes, copyToClipboard: true), diff --git a/lib/ui/payment/edit/payment_edit.dart b/lib/ui/payment/edit/payment_edit.dart index 5f2b29108..6c037d84b 100644 --- a/lib/ui/payment/edit/payment_edit.dart +++ b/lib/ui/payment/edit/payment_edit.dart @@ -625,7 +625,7 @@ class _PaymentableEditorState extends State { // If a client isn't selected or a client is selected but the client // doesn't have any more credits then don't show the picker if (widget.entityType == EntityType.credit && - ((payment.clientId ?? '').isEmpty || + (payment.clientId.isEmpty || (creditList.isEmpty && (paymentable.creditId ?? '').isEmpty))) { return SizedBox(); } else if (widget.entityType == EntityType.invoice && diff --git a/lib/ui/payment/payment_list_item.dart b/lib/ui/payment/payment_list_item.dart index dcfaa1647..2c25fe9b5 100644 --- a/lib/ui/payment/payment_list_item.dart +++ b/lib/ui/payment/payment_list_item.dart @@ -28,7 +28,7 @@ class PaymentListItem extends StatelessWidget { this.showSelected = true, }); - final PaymentEntity? payment; + final PaymentEntity payment; final String? filter; final bool showCheckbox; final bool isChecked; @@ -41,31 +41,31 @@ class PaymentListItem extends StatelessWidget { final uiState = state.uiState; final paymentUIState = uiState.paymentUIState; final textStyle = TextStyle(fontSize: 16); - final client = state.clientState.get(payment!.clientId); + final client = state.clientState.get(payment.clientId); final localization = AppLocalization.of(context); final filterMatch = filter != null && filter!.isNotEmpty - ? (payment!.matchesFilterValue(filter) ?? + ? (payment.matchesFilterValue(filter) ?? client.matchesFilterValue(filter)) : null; final mobileSubtitle = filterMatch ?? - (payment!.number ?? '') + ' • ' + formatDate(payment!.date, context); + payment.number + ' • ' + formatDate(payment.date, context); final textColor = Theme.of(context).textTheme.bodyLarge!.color; String desktopSubtitle = ''; - if (payment!.date.isNotEmpty) { - desktopSubtitle = formatDate(payment!.date, context); + if (payment.date.isNotEmpty) { + desktopSubtitle = formatDate(payment.date, context); } - if (payment!.transactionReference.isNotEmpty) { + if (payment.transactionReference.isNotEmpty) { if (desktopSubtitle.isNotEmpty) { desktopSubtitle += ' • '; } - desktopSubtitle += payment!.transactionReference; + desktopSubtitle += payment.transactionReference; } return DismissibleEntity( isSelected: isDesktop(context) && showSelected && - payment!.id == + payment.id == (uiState.isEditing ? paymentUIState.editing!.id : paymentUIState.selectedId), @@ -78,10 +78,10 @@ class PaymentListItem extends StatelessWidget { ? InkWell( onTap: () => onTap != null ? onTap!() - : selectEntity(entity: payment!, forceView: !showCheckbox), + : selectEntity(entity: payment, forceView: !showCheckbox), onLongPress: () => onTap != null ? null - : selectEntity(entity: payment!, longPress: true), + : selectEntity(entity: payment, longPress: true), child: Padding( padding: const EdgeInsets.only( left: 10, @@ -105,7 +105,7 @@ class PaymentListItem extends StatelessWidget { ), ) : ActionMenuButton( - entityActions: payment!.getActions( + entityActions: payment.getActions( userCompany: state.userCompany, client: client, includeEdit: true, @@ -121,11 +121,11 @@ class PaymentListItem extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - payment!.number, + payment.number, style: textStyle, overflow: TextOverflow.ellipsis, ), - if (!payment!.isActive) EntityStateLabel(payment) + if (!payment.isActive) EntityStateLabel(payment) ], ), ), @@ -152,7 +152,7 @@ class PaymentListItem extends StatelessWidget { ), SizedBox(width: 10), Text( - formatNumber(payment!.amount, context, + formatNumber(payment.amount, context, clientId: client.id)!, style: textStyle, textAlign: TextAlign.end, @@ -166,10 +166,10 @@ class PaymentListItem extends StatelessWidget { : ListTile( onTap: () => onTap != null ? onTap!() - : selectEntity(entity: payment!, forceView: !showCheckbox), + : selectEntity(entity: payment, forceView: !showCheckbox), onLongPress: () => onTap != null ? null - : selectEntity(entity: payment!, longPress: true), + : selectEntity(entity: payment, longPress: true), leading: showCheckbox ? IgnorePointer( child: Checkbox( @@ -192,8 +192,8 @@ class PaymentListItem extends StatelessWidget { ), ), Text( - formatNumber(payment!.amount, context, - clientId: payment!.clientId)!, + formatNumber(payment.amount, context, + clientId: payment.clientId)!, style: Theme.of(context).textTheme.titleMedium), ], ), @@ -214,11 +214,11 @@ class PaymentListItem extends StatelessWidget { ), Text( localization!.lookup( - 'payment_status_${payment!.calculatedStatusId}')!, + 'payment_status_${payment.calculatedStatusId}')!, style: TextStyle( color: PaymentStatusColors( state.prefState.colorThemeModel) - .colors[payment!.calculatedStatusId], + .colors[payment.calculatedStatusId], )), ], ), diff --git a/lib/ui/payment/view/payment_view.dart b/lib/ui/payment/view/payment_view.dart index 2924d5dfe..dcd9a997f 100644 --- a/lib/ui/payment/view/payment_view.dart +++ b/lib/ui/payment/view/payment_view.dart @@ -62,7 +62,7 @@ class _PaymentViewState extends State { if (payment.date.isNotEmpty) { fields[PaymentFields.date] = formatDate(payment.date, context); } - if ((payment.typeId ?? '').isNotEmpty) { + if (payment.typeId.isNotEmpty) { final paymentType = state.staticState.paymentTypeMap[payment.typeId]; if (paymentType != null) { fields[PaymentFields.typeId] = paymentType.name; @@ -133,7 +133,7 @@ class _PaymentViewState extends State { paymentable.createdAt), context), ), - if ((payment.companyGatewayId ?? '').isNotEmpty) ...[ + if (payment.companyGatewayId.isNotEmpty) ...[ ListTile( title: Text( '${localization.gateway} › ${companyGateway.label}'), diff --git a/lib/ui/project/project_list_item.dart b/lib/ui/project/project_list_item.dart index 3a5c12e9e..2ba1059e9 100644 --- a/lib/ui/project/project_list_item.dart +++ b/lib/ui/project/project_list_item.dart @@ -29,7 +29,7 @@ class ProjectListItem extends StatelessWidget { final UserEntity? user; final GestureTapCallback? onTap; final GestureTapCallback? onLongPress; - final ProjectEntity? project; + final ProjectEntity project; final String? filter; final Function(bool?)? onCheckboxChanged; final bool isChecked; @@ -40,9 +40,9 @@ class ProjectListItem extends StatelessWidget { final state = store.state; final uiState = state.uiState; final projectUIState = uiState.projectUIState; - final client = state.clientState.get(project!.clientId); + final client = state.clientState.get(project.clientId); final filterMatch = filter != null && filter!.isNotEmpty - ? (project!.matchesFilterValue(filter) ?? + ? (project.matchesFilterValue(filter) ?? client.matchesFilterValue(filter)) : null; final listUIState = projectUIState.listUIState; @@ -54,7 +54,7 @@ class ProjectListItem extends StatelessWidget { return DismissibleEntity( isSelected: isDesktop(context) && - project!.id == + project.id == (uiState.isEditing ? projectUIState.editing!.id : projectUIState.selectedId), @@ -65,10 +65,10 @@ class ProjectListItem extends StatelessWidget { return constraints.maxWidth > kTableListWidthCutoff ? InkWell( onTap: () => - onTap != null ? onTap!() : selectEntity(entity: project!), + onTap != null ? onTap!() : selectEntity(entity: project), onLongPress: () => onLongPress != null ? onLongPress!() - : selectEntity(entity: project!, longPress: true), + : selectEntity(entity: project, longPress: true), child: Padding( padding: const EdgeInsets.only( left: 10, @@ -97,7 +97,7 @@ class ProjectListItem extends StatelessWidget { ), ) : ActionMenuButton( - entityActions: project!.getActions( + entityActions: project.getActions( userCompany: state.userCompany, client: client, includeEdit: true, @@ -114,11 +114,11 @@ class ProjectListItem extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - project!.number ?? '', + project.number ?? '', style: textStyle, overflow: TextOverflow.ellipsis, ), - if (!project!.isActive) EntityStateLabel(project) + if (!project.isActive) EntityStateLabel(project) ], ), ), @@ -128,8 +128,8 @@ class ProjectListItem extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - project!.name + - (project!.documents.isNotEmpty + project.name + + (project.documents.isNotEmpty ? ' 📎' : ''), style: textStyle), @@ -150,7 +150,7 @@ class ProjectListItem extends StatelessWidget { Text( formatDuration( Duration( - minutes: (project!.budgetedHours * 60).toInt()), + minutes: (project.budgetedHours * 60).toInt()), showSeconds: false), style: textStyle, textAlign: TextAlign.end, @@ -161,10 +161,10 @@ class ProjectListItem extends StatelessWidget { ) : ListTile( onTap: () => - onTap != null ? onTap!() : selectEntity(entity: project!), + onTap != null ? onTap!() : selectEntity(entity: project), onLongPress: () => onLongPress != null ? onLongPress!() - : selectEntity(entity: project!, longPress: true), + : selectEntity(entity: project, longPress: true), leading: showCheckbox ? IgnorePointer( ignoring: listUIState.isInMultiselect(), @@ -183,8 +183,8 @@ class ProjectListItem extends StatelessWidget { children: [ Expanded( child: Text( - project!.name + - (project!.documents.isNotEmpty ? ' 📎' : ''), + project.name + + (project.documents.isNotEmpty ? ' 📎' : ''), style: Theme.of(context).textTheme.titleMedium, ), ), @@ -192,7 +192,7 @@ class ProjectListItem extends StatelessWidget { formatDuration( Duration( minutes: - (project!.budgetedHours * 60).toInt()), + (project.budgetedHours * 60).toInt()), showSeconds: false), style: Theme.of(context).textTheme.titleMedium), ], @@ -203,7 +203,7 @@ class ProjectListItem extends StatelessWidget { children: [ Text( filterMatch == null - ? project!.number + ' • ' + client.displayName + ? project.number + ' • ' + client.displayName : filterMatch, maxLines: 3, overflow: TextOverflow.ellipsis), diff --git a/lib/ui/project/project_list_vm.dart b/lib/ui/project/project_list_vm.dart index de3ea11c2..e5fc748aa 100644 --- a/lib/ui/project/project_list_vm.dart +++ b/lib/ui/project/project_list_vm.dart @@ -43,7 +43,7 @@ class ProjectListBuilder extends StatelessWidget { itemBuilder: (BuildContext context, index) { final state = viewModel.state; final projectId = viewModel.projectList[index]; - final project = viewModel.projectMap[projectId]; + final project = viewModel.projectMap[projectId]!; final listState = state.getListState(EntityType.project); final isInMultiselect = listState.isInMultiselect(); @@ -51,7 +51,7 @@ class ProjectListBuilder extends StatelessWidget { user: state.user, filter: viewModel.filter, project: project, - isChecked: isInMultiselect && listState.isSelected(project!.id), + isChecked: isInMultiselect && listState.isSelected(project.id), ); }); }, diff --git a/lib/ui/project/project_presenter.dart b/lib/ui/project/project_presenter.dart index 810576bf7..032251f2d 100644 --- a/lib/ui/project/project_presenter.dart +++ b/lib/ui/project/project_presenter.dart @@ -69,7 +69,7 @@ class ProjectPresenter extends EntityPresenter { return Text(formatNumber(project.budgetedHours, context, formatNumberType: FormatNumberType.double)!); case ProjectFields.number: - return Text(project.number ?? ''); + return Text(project.number); case ProjectFields.customValue1: return Text(presentCustomField(context, project.customValue1)!); case ProjectFields.customValue2: diff --git a/lib/ui/project/view/project_view_overview.dart b/lib/ui/project/view/project_view_overview.dart index 6c707371b..c75bb6903 100644 --- a/lib/ui/project/view/project_view_overview.dart +++ b/lib/ui/project/view/project_view_overview.dart @@ -111,7 +111,7 @@ class _ProjectOverviewState extends State { Duration(minutes: (project.budgetedHours * 60).toInt())), ), ListDivider(), - if ((project.privateNotes ?? '').isNotEmpty) ...[ + if (project.privateNotes.isNotEmpty) ...[ IconMessage(project.privateNotes, iconData: Icons.lock, copyToClipboard: true), ListDivider() @@ -160,7 +160,7 @@ class _ProjectOverviewState extends State { FieldGrid(fields), ]); - if ((project.publicNotes ?? '').isNotEmpty) { + if (project.publicNotes.isNotEmpty) { widgets.addAll([ IconMessage(project.publicNotes, copyToClipboard: true), ListDivider() diff --git a/lib/ui/purchase_order/purchase_order_list_item.dart b/lib/ui/purchase_order/purchase_order_list_item.dart index 97fb78182..6a6f96a57 100644 --- a/lib/ui/purchase_order/purchase_order_list_item.dart +++ b/lib/ui/purchase_order/purchase_order_list_item.dart @@ -116,7 +116,7 @@ class PurchaseOrderListItem extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - (purchaseOrder.number ?? '').isEmpty + purchaseOrder.number.isEmpty ? localization!.pending : purchaseOrder.number, style: textStyle, diff --git a/lib/ui/quote/quote_list_item.dart b/lib/ui/quote/quote_list_item.dart index 90702d59f..061a856e1 100644 --- a/lib/ui/quote/quote_list_item.dart +++ b/lib/ui/quote/quote_list_item.dart @@ -206,7 +206,7 @@ class QuoteListItem extends StatelessWidget { children: [ Expanded( child: filterMatch == null - ? Text((((quote.number ?? '').isEmpty + ? Text(((quote.number.isEmpty ? localization!.pending : quote.number) + ' • ' + diff --git a/lib/ui/quote/quote_presenter.dart b/lib/ui/quote/quote_presenter.dart index be6667608..94faa563b 100644 --- a/lib/ui/quote/quote_presenter.dart +++ b/lib/ui/quote/quote_presenter.dart @@ -70,9 +70,8 @@ class QuotePresenter extends EntityPresenter { case QuoteFields.status: return EntityStatusChip(entity: quote, showState: true); case QuoteFields.number: - return Text((quote.number ?? '').isEmpty - ? localization!.pending - : quote.number); + return Text( + quote.number.isEmpty ? localization!.pending : quote.number); case QuoteFields.client: return LinkTextRelatedEntity(entity: client, relation: quote); case QuoteFields.date: diff --git a/lib/ui/recurring_expense/recurring_expense_list_item.dart b/lib/ui/recurring_expense/recurring_expense_list_item.dart index 28a95c795..f97121d9e 100644 --- a/lib/ui/recurring_expense/recurring_expense_list_item.dart +++ b/lib/ui/recurring_expense/recurring_expense_list_item.dart @@ -19,7 +19,7 @@ import 'package:invoiceninja_flutter/utils/platforms.dart'; class RecurringExpenseListItem extends StatelessWidget { const RecurringExpenseListItem({ required this.expense, - this.filter, + required this.filter, this.onTap, this.onCheckboxChanged, this.showCheckbox = true, @@ -29,7 +29,7 @@ class RecurringExpenseListItem extends StatelessWidget { final Function(bool?)? onCheckboxChanged; final GestureTapCallback? onTap; - final ExpenseEntity? expense; + final ExpenseEntity expense; final String? filter; final bool showCheckbox; final bool isDismissible; @@ -41,18 +41,18 @@ class RecurringExpenseListItem extends StatelessWidget { final state = store.state; final uiState = state.uiState; final expenseUIState = uiState.recurringExpenseUIState; - final client = state.clientState.get(expense!.clientId!); - final vendor = state.vendorState.get(expense!.vendorId!); - final category = state.expenseCategoryState.get(expense!.categoryId); + final client = state.clientState.get(expense.clientId!); + final vendor = state.vendorState.get(expense.vendorId!); + final category = state.expenseCategoryState.get(expense.categoryId); final filterMatch = filter != null && filter!.isNotEmpty - ? (expense!.matchesFilterValue(filter) ?? + ? (expense.matchesFilterValue(filter) ?? client.matchesFilterValue(filter)) : null; final listUIState = expenseUIState.listUIState; final isInMultiselect = listUIState.isInMultiselect(); final showCheckbox = onCheckboxChanged != null || isInMultiselect; final isChecked = isDismissible - ? (isInMultiselect && listUIState.isSelected(expense!.id)) + ? (isInMultiselect && listUIState.isSelected(expense.id)) : this.isChecked; final textStyle = TextStyle(fontSize: 16); final textColor = Theme.of(context).textTheme.bodyLarge!.color; @@ -62,8 +62,8 @@ class RecurringExpenseListItem extends StatelessWidget { subtitle = filterMatch; } else if (client != null || vendor != null || category != null) { final parts = []; - if (expense!.nextSendDate.isNotEmpty) { - parts.add(formatDate(expense!.nextSendDate, context)); + if (expense.nextSendDate.isNotEmpty) { + parts.add(formatDate(expense.nextSendDate, context)); } if (category.isOld) { parts.add(category.name); @@ -81,7 +81,7 @@ class RecurringExpenseListItem extends StatelessWidget { showMultiselect: this.showCheckbox, isDismissible: isDismissible, isSelected: isDesktop(context) && - expense!.id == + expense.id == (uiState.isEditing ? expenseUIState.editing!.id : expenseUIState.selectedId), @@ -92,9 +92,9 @@ class RecurringExpenseListItem extends StatelessWidget { return constraints.maxWidth > kTableListWidthCutoff ? InkWell( onTap: () => - onTap != null ? onTap!() : selectEntity(entity: expense!), + onTap != null ? onTap!() : selectEntity(entity: expense), onLongPress: () => - selectEntity(entity: expense!, longPress: true), + selectEntity(entity: expense, longPress: true), child: Padding( padding: const EdgeInsets.only( left: 10, @@ -123,7 +123,7 @@ class RecurringExpenseListItem extends StatelessWidget { ), ) : ActionMenuButton( - entityActions: expense!.getActions( + entityActions: expense.getActions( userCompany: state.userCompany, includeEdit: true, ), @@ -139,11 +139,11 @@ class RecurringExpenseListItem extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - expense!.number, + expense.number, style: textStyle, overflow: TextOverflow.ellipsis, ), - if (!expense!.isActive) EntityStateLabel(expense) + if (!expense.isActive) EntityStateLabel(expense) ], ), ), @@ -153,8 +153,8 @@ class RecurringExpenseListItem extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - (expense!.publicNotes ?? '') + - (expense!.documents.isNotEmpty ? ' 📎' : ''), + (expense.publicNotes ?? '') + + (expense.documents.isNotEmpty ? ' 📎' : ''), style: textStyle, maxLines: 1, ), @@ -173,8 +173,8 @@ class RecurringExpenseListItem extends StatelessWidget { ), SizedBox(width: 8), Text( - formatNumber(expense!.convertedAmount, context, - currencyId: expense!.currencyId)!, + formatNumber(expense.convertedAmount, context, + currencyId: expense.currencyId)!, style: textStyle, textAlign: TextAlign.end, ), @@ -186,9 +186,9 @@ class RecurringExpenseListItem extends StatelessWidget { ) : ListTile( onTap: () => - onTap != null ? onTap!() : selectEntity(entity: expense!), + onTap != null ? onTap!() : selectEntity(entity: expense), onLongPress: () => - selectEntity(entity: expense!, longPress: true), + selectEntity(entity: expense, longPress: true), leading: showCheckbox ? IgnorePointer( ignoring: listUIState.isInMultiselect(), @@ -207,17 +207,17 @@ class RecurringExpenseListItem extends StatelessWidget { children: [ Expanded( child: Text( - (expense!.publicNotes.isEmpty - ? expense!.number - : expense!.publicNotes) + - (expense!.documents.isNotEmpty ? ' 📎' : ''), + (expense.publicNotes.isEmpty + ? expense.number + : expense.publicNotes) + + (expense.documents.isNotEmpty ? ' 📎' : ''), style: Theme.of(context).textTheme.titleMedium, maxLines: 1, ), ), Text( - formatNumber(expense!.convertedAmount, context, - currencyId: expense!.currencyId)!, + formatNumber(expense.convertedAmount, context, + currencyId: expense.currencyId)!, style: Theme.of(context).textTheme.titleMedium), ], ), diff --git a/lib/ui/recurring_expense/recurring_expense_list_vm.dart b/lib/ui/recurring_expense/recurring_expense_list_vm.dart index 97b470d11..edbd340ca 100644 --- a/lib/ui/recurring_expense/recurring_expense_list_vm.dart +++ b/lib/ui/recurring_expense/recurring_expense_list_vm.dart @@ -44,7 +44,7 @@ class RecurringExpenseListBuilder extends StatelessWidget { final state = viewModel.state; final recurringExpenseId = viewModel.recurringExpenseList[index]; final recurringExpense = - viewModel.recurringExpenseMap[recurringExpenseId]; + viewModel.recurringExpenseMap[recurringExpenseId]!; final listState = state.getListState(EntityType.recurringExpense); final isInMultiselect = listState.isInMultiselect(); @@ -52,7 +52,7 @@ class RecurringExpenseListBuilder extends StatelessWidget { filter: viewModel.filter, expense: recurringExpense, isChecked: isInMultiselect && - listState.isSelected(recurringExpense!.id), + listState.isSelected(recurringExpense.id), ); }); }, diff --git a/lib/ui/recurring_invoice/recurring_invoice_list_item.dart b/lib/ui/recurring_invoice/recurring_invoice_list_item.dart index 512cf4a80..351f84067 100644 --- a/lib/ui/recurring_invoice/recurring_invoice_list_item.dart +++ b/lib/ui/recurring_invoice/recurring_invoice_list_item.dart @@ -216,7 +216,7 @@ class RecurringInvoiceListItem extends StatelessWidget { Expanded( child: filterMatch == null ? Text( - (((invoice.number ?? '').isEmpty + ((invoice.number.isEmpty ? localization.pending : invoice.number) + (invoice.nextSendDate.isNotEmpty diff --git a/lib/ui/recurring_invoice/recurring_invoice_presenter.dart b/lib/ui/recurring_invoice/recurring_invoice_presenter.dart index a607d03bf..4aa850e73 100644 --- a/lib/ui/recurring_invoice/recurring_invoice_presenter.dart +++ b/lib/ui/recurring_invoice/recurring_invoice_presenter.dart @@ -52,76 +52,75 @@ class RecurringInvoicePresenter extends EntityPresenter { Widget getField({String? field, required BuildContext context}) { final localization = AppLocalization.of(context); final state = StoreProvider.of(context).state; - final invoice = entity as InvoiceEntity?; + final invoice = entity as InvoiceEntity; switch (field) { case RecurringInvoiceFields.status: return EntityStatusChip(entity: invoice, showState: true); case RecurringInvoiceFields.number: - return Text((invoice!.number ?? '').isEmpty - ? localization!.pending - : invoice.number); + return Text( + invoice.number.isEmpty ? localization!.pending : invoice.number); case RecurringInvoiceFields.client: - final client = state.clientState.get(invoice!.clientId); + final client = state.clientState.get(invoice.clientId); return LinkTextRelatedEntity(entity: client, relation: invoice); case RecurringInvoiceFields.date: - return Text(formatDate(invoice!.date, context)); + return Text(formatDate(invoice.date, context)); case RecurringInvoiceFields.reminder1Sent: - return Text(formatDate(invoice!.reminder1Sent, context)); + return Text(formatDate(invoice.reminder1Sent, context)); case RecurringInvoiceFields.reminder2Sent: - return Text(formatDate(invoice!.reminder2Sent, context)); + return Text(formatDate(invoice.reminder2Sent, context)); case RecurringInvoiceFields.reminder3Sent: - return Text(formatDate(invoice!.reminder3Sent, context)); + return Text(formatDate(invoice.reminder3Sent, context)); case RecurringInvoiceFields.reminderLastSent: - return Text(formatDate(invoice!.reminderLastSent, context)); + return Text(formatDate(invoice.reminderLastSent, context)); case RecurringInvoiceFields.amount: return Align( alignment: Alignment.centerRight, - child: Text(formatNumber(invoice!.amount, context, + child: Text(formatNumber(invoice.amount, context, clientId: invoice.clientId)!), ); case RecurringInvoiceFields.customValue1: - return Text(presentCustomField(context, invoice!.customValue1)!); + return Text(presentCustomField(context, invoice.customValue1)!); case RecurringInvoiceFields.customValue2: - return Text(presentCustomField(context, invoice!.customValue2)!); + return Text(presentCustomField(context, invoice.customValue2)!); case RecurringInvoiceFields.customValue3: - return Text(presentCustomField(context, invoice!.customValue3)!); + return Text(presentCustomField(context, invoice.customValue3)!); case RecurringInvoiceFields.customValue4: - return Text(presentCustomField(context, invoice!.customValue4)!); + return Text(presentCustomField(context, invoice.customValue4)!); case RecurringInvoiceFields.publicNotes: - return TableTooltip(message: invoice!.publicNotes); + return TableTooltip(message: invoice.publicNotes); case RecurringInvoiceFields.privateNotes: - return TableTooltip(message: invoice!.privateNotes); + return TableTooltip(message: invoice.privateNotes); case RecurringInvoiceFields.discount: - return Text(invoice!.isAmountDiscount + return Text(invoice.isAmountDiscount ? formatNumber(invoice.discount, context, formatNumberType: FormatNumberType.money, clientId: invoice.clientId)! : formatNumber(invoice.discount, context, formatNumberType: FormatNumberType.percent)!); case RecurringInvoiceFields.poNumber: - return Text(invoice!.poNumber); + return Text(invoice.poNumber); case RecurringInvoiceFields.documents: - return Text('${invoice!.documents.length}'); + return Text('${invoice.documents.length}'); case RecurringInvoiceFields.taxAmount: - return Text(formatNumber(invoice!.taxAmount, context, + return Text(formatNumber(invoice.taxAmount, context, clientId: invoice.clientId)!); case RecurringInvoiceFields.exchangeRate: - return Text(formatNumber(invoice!.exchangeRate, context, + return Text(formatNumber(invoice.exchangeRate, context, formatNumberType: FormatNumberType.double)!); case RecurringInvoiceFields.remainingCycles: - return Text(invoice!.remainingCycles == -1 + return Text(invoice.remainingCycles == -1 ? localization!.endless : '${invoice.remainingCycles}'); case RecurringInvoiceFields.nextSendDate: - return Text(invoice!.nextSendDatetime.isNotEmpty + return Text(invoice.nextSendDatetime.isNotEmpty ? formatDate(invoice.nextSendDatetime, context, showTime: true, showSeconds: false) : formatDate(invoice.nextSendDate, context)); case RecurringInvoiceFields.frequency: - return Text(localization!.lookup(kFrequencies[invoice!.frequencyId])!); + return Text(localization!.lookup(kFrequencies[invoice.frequencyId])!); case RecurringInvoiceFields.dueDateDays: - return Text(invoice!.dueDateDays == 'terms' + return Text(invoice.dueDateDays == 'terms' ? localization!.paymentTerm : invoice.dueDateDays == 'on_receipt' ? localization!.dueOnReceipt! @@ -132,7 +131,7 @@ class RecurringInvoicePresenter extends EntityPresenter { : localization!.dayCount .replaceFirst(':count', '${invoice.dueDateDays}')); case RecurringInvoiceFields.autoBill: - return Text(localization!.lookup(invoice!.autoBill)!); + return Text(localization!.lookup(invoice.autoBill)!); } return super.getField(field: field, context: context); diff --git a/lib/ui/reports/reports_screen.dart b/lib/ui/reports/reports_screen.dart index 47ff40f64..f439c4731 100644 --- a/lib/ui/reports/reports_screen.dart +++ b/lib/ui/reports/reports_screen.dart @@ -722,7 +722,7 @@ class TotalsDataTable extends StatelessWidget { reportResult.columns.length > reportSettings.sortTotalsIndex ? reportSettings.sortTotalsIndex : null, - sortAscending: reportSettings.sortTotalsAscending ?? true, + sortAscending: reportSettings.sortTotalsAscending, columns: reportResult.totalColumns( context, (index, ascending) => @@ -925,7 +925,10 @@ class ReportResult { return true; } - static bool matchString({required String filter, String? value}) { + static bool matchString({ + required String filter, + String? value, + }) { filter = filter.trim(); if (filter.isEmpty) { @@ -933,7 +936,7 @@ class ReportResult { } value = (value ?? '').toLowerCase(); - filter = (filter ?? '').toLowerCase(); + filter = filter.toLowerCase(); if (filter == 'null' && value.isEmpty) { return true; @@ -1120,7 +1123,7 @@ class ReportResult { )) else if (getReportColumnType(column, context) == ReportColumnType.age) DataCell(AppDropdownButton( - value: (textEditingControllers[column]!.text ?? '').isNotEmpty && + value: (textEditingControllers[column]!.text).isNotEmpty && textEditingControllers[column]!.text != 'null' ? textEditingControllers[column]!.text : null, diff --git a/lib/ui/reports/task_report.dart b/lib/ui/reports/task_report.dart index 44bb5ecaa..3e3344af1 100644 --- a/lib/ui/reports/task_report.dart +++ b/lib/ui/reports/task_report.dart @@ -164,10 +164,10 @@ ReportResult taskReport( value = task.description; break; case TaskReportFields.invoice: - value = invoice.listDisplayName ?? ''; + value = invoice.listDisplayName; break; case TaskReportFields.invoice_amount: - value = invoice.amount ?? ''; + value = invoice.amount; break; case TaskReportFields.invoice_date: value = invoice.isNew ? '' : invoice.date; diff --git a/lib/ui/vendor/view/vendor_view_overview.dart b/lib/ui/vendor/view/vendor_view_overview.dart index ab520770e..7ca34f010 100644 --- a/lib/ui/vendor/view/vendor_view_overview.dart +++ b/lib/ui/vendor/view/vendor_view_overview.dart @@ -152,7 +152,7 @@ class VendorOverview extends StatelessWidget { vendor.id, state.transactionState.map) .present(localization.active, localization.archived), ), - if ((vendor.publicNotes ?? '').isNotEmpty) ...[ + if (vendor.publicNotes.isNotEmpty) ...[ IconMessage(vendor.publicNotes, copyToClipboard: true), ListDivider() ], diff --git a/lib/utils/platforms.dart b/lib/utils/platforms.dart index 07aca25a6..43ec45231 100644 --- a/lib/utils/platforms.dart +++ b/lib/utils/platforms.dart @@ -276,8 +276,7 @@ AppLayout calculateLayout(BuildContext context) { } AppLayout getLayout(BuildContext context) => - StoreProvider.of(context).state.prefState.appLayout ?? - AppLayout.mobile; + StoreProvider.of(context).state.prefState.appLayout; bool isMobile(BuildContext context) => getLayout(context) == AppLayout.mobile; diff --git a/lib/utils/strings.dart b/lib/utils/strings.dart index cdbe588ec..4beba28fa 100644 --- a/lib/utils/strings.dart +++ b/lib/utils/strings.dart @@ -34,7 +34,7 @@ String toCamelCase(String subject) { } String toSpaceCase(String value) { - if ((value ?? '').isEmpty) { + if (value.isEmpty) { return ''; }