Null safety
This commit is contained in:
parent
fbd8b8f5ba
commit
e22c4a5228
|
|
@ -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,
|
||||
);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
],
|
||||
|
|
|
|||
|
|
@ -250,9 +250,8 @@ class InvoiceEditDesktopState extends State<InvoiceEditDesktop>
|
|||
!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<InvoiceEditDesktop>
|
|||
))
|
||||
.toList()),
|
||||
DatePicker(
|
||||
labelText: (invoice.lastSentDate ?? '').isNotEmpty
|
||||
labelText: invoice.lastSentDate.isNotEmpty
|
||||
? localization.nextSendDate
|
||||
: localization.startDate,
|
||||
onSelected: (date, _) {
|
||||
|
|
|
|||
|
|
@ -223,7 +223,7 @@ class InvoiceEditDetailsState extends State<InvoiceEditDetails> {
|
|||
))
|
||||
.toList()),
|
||||
DatePicker(
|
||||
labelText: (invoice.lastSentDate ?? '').isNotEmpty
|
||||
labelText: invoice.lastSentDate.isNotEmpty
|
||||
? localization.nextSendDate
|
||||
: localization.startDate,
|
||||
onSelected: (date, _) => viewModel
|
||||
|
|
|
|||
|
|
@ -448,10 +448,10 @@ class _InvoiceEditItemsDesktopState extends State<InvoiceEditItemsDesktop> {
|
|||
..._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,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ class _InvoiceViewHistoryState extends State<InvoiceViewHistory> {
|
|||
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!);
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -625,7 +625,7 @@ class _PaymentableEditorState extends State<PaymentableEditor> {
|
|||
// 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 &&
|
||||
|
|
|
|||
|
|
@ -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: <Widget>[
|
||||
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],
|
||||
)),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ class _PaymentViewState extends State<PaymentView> {
|
|||
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<PaymentView> {
|
|||
paymentable.createdAt),
|
||||
context),
|
||||
),
|
||||
if ((payment.companyGatewayId ?? '').isNotEmpty) ...[
|
||||
if (payment.companyGatewayId.isNotEmpty) ...[
|
||||
ListTile(
|
||||
title: Text(
|
||||
'${localization.gateway} › ${companyGateway.label}'),
|
||||
|
|
|
|||
|
|
@ -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: <Widget>[
|
||||
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: <Widget>[
|
||||
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: <Widget>[
|
||||
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: <Widget>[
|
||||
Text(
|
||||
filterMatch == null
|
||||
? project!.number + ' • ' + client.displayName
|
||||
? project.number + ' • ' + client.displayName
|
||||
: filterMatch,
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.ellipsis),
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
);
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ class _ProjectOverviewState extends State<ProjectOverview> {
|
|||
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<ProjectOverview> {
|
|||
FieldGrid(fields),
|
||||
]);
|
||||
|
||||
if ((project.publicNotes ?? '').isNotEmpty) {
|
||||
if (project.publicNotes.isNotEmpty) {
|
||||
widgets.addAll([
|
||||
IconMessage(project.publicNotes, copyToClipboard: true),
|
||||
ListDivider()
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ class PurchaseOrderListItem extends StatelessWidget {
|
|||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
(purchaseOrder.number ?? '').isEmpty
|
||||
purchaseOrder.number.isEmpty
|
||||
? localization!.pending
|
||||
: purchaseOrder.number,
|
||||
style: textStyle,
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ class QuoteListItem extends StatelessWidget {
|
|||
children: <Widget>[
|
||||
Expanded(
|
||||
child: filterMatch == null
|
||||
? Text((((quote.number ?? '').isEmpty
|
||||
? Text(((quote.number.isEmpty
|
||||
? localization!.pending
|
||||
: quote.number) +
|
||||
' • ' +
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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 = <String>[];
|
||||
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: <Widget>[
|
||||
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: <Widget>[
|
||||
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: <Widget>[
|
||||
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),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
);
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -52,76 +52,75 @@ class RecurringInvoicePresenter extends EntityPresenter {
|
|||
Widget getField({String? field, required BuildContext context}) {
|
||||
final localization = AppLocalization.of(context);
|
||||
final state = StoreProvider.of<AppState>(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);
|
||||
|
|
|
|||
|
|
@ -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<String>(
|
||||
value: (textEditingControllers[column]!.text ?? '').isNotEmpty &&
|
||||
value: (textEditingControllers[column]!.text).isNotEmpty &&
|
||||
textEditingControllers[column]!.text != 'null'
|
||||
? textEditingControllers[column]!.text
|
||||
: null,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
],
|
||||
|
|
|
|||
|
|
@ -276,8 +276,7 @@ AppLayout calculateLayout(BuildContext context) {
|
|||
}
|
||||
|
||||
AppLayout getLayout(BuildContext context) =>
|
||||
StoreProvider.of<AppState>(context).state.prefState.appLayout ??
|
||||
AppLayout.mobile;
|
||||
StoreProvider.of<AppState>(context).state.prefState.appLayout;
|
||||
|
||||
bool isMobile(BuildContext context) => getLayout(context) == AppLayout.mobile;
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ String toCamelCase(String subject) {
|
|||
}
|
||||
|
||||
String toSpaceCase(String value) {
|
||||
if ((value ?? '').isEmpty) {
|
||||
if (value.isEmpty) {
|
||||
return '';
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue