Null safety
This commit is contained in:
parent
df7e3576b1
commit
fbd8b8f5ba
|
|
@ -236,18 +236,17 @@ class _CompanyGatewayEditState extends State<CompanyGatewayEdit>
|
|||
AppDropdownButton<String>(
|
||||
labelText: localization.captureCard,
|
||||
value: companyGateway.tokenBilling,
|
||||
selectedItemBuilder:
|
||||
(companyGateway.tokenBilling ?? '').isEmpty
|
||||
? null
|
||||
: (context) => [
|
||||
SettingsEntity.AUTO_BILL_ALWAYS,
|
||||
SettingsEntity.AUTO_BILL_OPT_OUT,
|
||||
SettingsEntity.AUTO_BILL_OPT_IN,
|
||||
SettingsEntity.AUTO_BILL_OFF,
|
||||
]
|
||||
.map((type) =>
|
||||
Text(localization.lookup(type)!))
|
||||
.toList(),
|
||||
selectedItemBuilder: companyGateway.tokenBilling.isEmpty
|
||||
? null
|
||||
: (context) => [
|
||||
SettingsEntity.AUTO_BILL_ALWAYS,
|
||||
SettingsEntity.AUTO_BILL_OPT_OUT,
|
||||
SettingsEntity.AUTO_BILL_OPT_IN,
|
||||
SettingsEntity.AUTO_BILL_OFF,
|
||||
]
|
||||
.map((type) =>
|
||||
Text(localization.lookup(type)!))
|
||||
.toList(),
|
||||
onChanged: (dynamic value) => viewModel.onChanged(
|
||||
companyGateway
|
||||
.rebuild((b) => b..tokenBilling = value)),
|
||||
|
|
@ -767,11 +766,11 @@ class _LimitEditorState extends State<LimitEditor> {
|
|||
|
||||
_minController!.text = settings.minLimit == -1
|
||||
? ''
|
||||
: formatNumber((settings.minLimit ?? 0).toDouble(), context,
|
||||
: formatNumber(settings.minLimit.toDouble(), context,
|
||||
formatNumberType: FormatNumberType.inputMoney)!;
|
||||
_maxController!.text = settings.maxLimit == -1
|
||||
? ''
|
||||
: formatNumber((settings.maxLimit ?? 0).toDouble(), context,
|
||||
: formatNumber(settings.maxLimit.toDouble(), context,
|
||||
formatNumberType: FormatNumberType.inputMoney)!;
|
||||
|
||||
_minController!.addListener(_onTextChange);
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ class CreditListItem extends StatelessWidget {
|
|||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
(credit.number ?? '').isEmpty
|
||||
credit.number.isEmpty
|
||||
? localization!.pending
|
||||
: credit.number,
|
||||
style: textStyle,
|
||||
|
|
@ -211,7 +211,7 @@ class CreditListItem extends StatelessWidget {
|
|||
children: <Widget>[
|
||||
Expanded(
|
||||
child: filterMatch == null
|
||||
? Text((((credit.number ?? '').isEmpty
|
||||
? Text(((credit.number.isEmpty
|
||||
? localization!.pending
|
||||
: credit.number) +
|
||||
' • ' +
|
||||
|
|
|
|||
|
|
@ -70,9 +70,8 @@ class CreditPresenter extends EntityPresenter {
|
|||
case CreditFields.status:
|
||||
return EntityStatusChip(entity: credit, showState: true);
|
||||
case CreditFields.number:
|
||||
return Text((credit.number ?? '').isEmpty
|
||||
? localization!.pending
|
||||
: credit.number);
|
||||
return Text(
|
||||
credit.number.isEmpty ? localization!.pending : credit.number);
|
||||
case CreditFields.client:
|
||||
return LinkTextRelatedEntity(entity: client, relation: credit);
|
||||
case CreditFields.date:
|
||||
|
|
@ -146,7 +145,7 @@ class CreditPresenter extends EntityPresenter {
|
|||
return SizedBox();
|
||||
}
|
||||
if (field == CreditFields.contactName) {
|
||||
return Text(contact.fullName ?? '');
|
||||
return Text(contact.fullName);
|
||||
}
|
||||
return CopyToClipboard(
|
||||
value: contact.email,
|
||||
|
|
|
|||
|
|
@ -865,7 +865,7 @@ class __DashboardPanelState extends State<_DashboardPanel> {
|
|||
title: widget.title,
|
||||
onDateSelected: widget.onDateSelected,
|
||||
onSelected: widget.onSelected as dynamic Function(),
|
||||
currencyId: (settings.currencyId ?? '').isNotEmpty
|
||||
currencyId: settings.currencyId.isNotEmpty
|
||||
? settings.currencyId
|
||||
: state.company!.currencyId,
|
||||
);
|
||||
|
|
@ -996,7 +996,7 @@ class __OverviewPanelState extends State<_OverviewPanel> {
|
|||
title: widget.title,
|
||||
onSelected: () => null,
|
||||
onDateSelected: widget.onDateSelected,
|
||||
currencyId: (settings.currencyId ?? '').isNotEmpty
|
||||
currencyId: settings.currencyId.isNotEmpty
|
||||
? settings.currencyId
|
||||
: state.company!.currencyId,
|
||||
isOverview: true,
|
||||
|
|
|
|||
|
|
@ -405,7 +405,7 @@ class ExpenseSidbar extends StatelessWidget {
|
|||
itemCount: recentExpenses.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return ExpenseListItem(
|
||||
expense: recentExpenses[index],
|
||||
expense: recentExpenses[index]!,
|
||||
showCheckbox: false,
|
||||
showSelected: false,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ class _DesignEditState extends State<DesignEdit>
|
|||
kDesignBody: _bodyController.text.trim(),
|
||||
kDesignFooter: _footerController.text.trim(),
|
||||
kDesignProducts: _productsController.text.trim(),
|
||||
kDesignTasks: _tasksController.text.trim() ?? '',
|
||||
kDesignTasks: _tasksController.text.trim(),
|
||||
kDesignIncludes: _includesController.text.trim()
|
||||
})));
|
||||
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ class ExpenseEditDetailsState extends State<ExpenseEditDetails> {
|
|||
(client as ClientEntity).settings.currencyId ??
|
||||
company.currencyId;
|
||||
viewModel.onChanged!(expense.rebuild((b) => b
|
||||
..clientId = client.id ?? ''
|
||||
..clientId = client.id
|
||||
..invoiceCurrencyId = currencyId));
|
||||
},
|
||||
onAddPressed: (completer) {
|
||||
|
|
@ -195,7 +195,7 @@ class ExpenseEditDetailsState extends State<ExpenseEditDetails> {
|
|||
final project = store.state.projectState.get(selectedId);
|
||||
viewModel.onChanged!(expense.rebuild((b) => b
|
||||
..projectId = project.id
|
||||
..clientId = (project.clientId ?? '').isNotEmpty
|
||||
..clientId = project.clientId.isNotEmpty
|
||||
? project.clientId
|
||||
: expense.clientId));
|
||||
},
|
||||
|
|
@ -361,7 +361,7 @@ class ExpenseEditDetailsState extends State<ExpenseEditDetails> {
|
|||
))
|
||||
.toList()),
|
||||
DatePicker(
|
||||
labelText: (expense.lastSentDate ?? '').isNotEmpty
|
||||
labelText: expense.lastSentDate.isNotEmpty
|
||||
? localization.nextSendDate
|
||||
: localization.startDate,
|
||||
onSelected: (date, _) {
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class ExpenseListItem extends StatelessWidget {
|
|||
|
||||
final Function(bool?)? onCheckboxChanged;
|
||||
final GestureTapCallback? onTap;
|
||||
final ExpenseEntity? expense;
|
||||
final ExpenseEntity expense;
|
||||
final String? filter;
|
||||
final bool showCheckbox;
|
||||
final bool isDismissible;
|
||||
|
|
@ -48,11 +48,11 @@ class ExpenseListItem extends StatelessWidget {
|
|||
final uiState = state.uiState;
|
||||
final expenseUIState = uiState.expenseUIState;
|
||||
final listUIState = expenseUIState.listUIState;
|
||||
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 textStyle = TextStyle(fontSize: 16);
|
||||
|
|
@ -63,7 +63,7 @@ class ExpenseListItem extends StatelessWidget {
|
|||
subtitle = filterMatch;
|
||||
} else if (client != null || vendor != null || category != null) {
|
||||
final parts = <String>[
|
||||
formatDate(expense!.date, context),
|
||||
formatDate(expense.date, context),
|
||||
];
|
||||
if (category.isOld) {
|
||||
parts.add(category.name);
|
||||
|
|
@ -82,7 +82,7 @@ class ExpenseListItem extends StatelessWidget {
|
|||
isDismissible: isDismissible,
|
||||
isSelected: isDesktop(context) &&
|
||||
showSelected &&
|
||||
expense!.id ==
|
||||
expense.id ==
|
||||
(uiState.isEditing
|
||||
? expenseUIState.editing!.id
|
||||
: expenseUIState.selectedId),
|
||||
|
|
@ -93,10 +93,10 @@ class ExpenseListItem extends StatelessWidget {
|
|||
return constraints.maxWidth > kTableListWidthCutoff
|
||||
? InkWell(
|
||||
onTap: () =>
|
||||
onTap != null ? onTap!() : selectEntity(entity: expense!),
|
||||
onTap != null ? onTap!() : selectEntity(entity: expense),
|
||||
onLongPress: () => onTap != null
|
||||
? null
|
||||
: selectEntity(entity: expense!, longPress: true),
|
||||
: selectEntity(entity: expense, longPress: true),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 10,
|
||||
|
|
@ -125,7 +125,7 @@ class ExpenseListItem extends StatelessWidget {
|
|||
),
|
||||
)
|
||||
: ActionMenuButton(
|
||||
entityActions: expense!.getActions(
|
||||
entityActions: expense.getActions(
|
||||
userCompany: state.userCompany,
|
||||
includeEdit: true,
|
||||
),
|
||||
|
|
@ -141,11 +141,11 @@ class ExpenseListItem 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)
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
@ -155,12 +155,12 @@ class ExpenseListItem extends StatelessWidget {
|
|||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
(expense!.publicNotes ?? '') +
|
||||
(expense!.documents.isNotEmpty ? ' 📎' : ''),
|
||||
expense.publicNotes +
|
||||
(expense.documents.isNotEmpty ? ' 📎' : ''),
|
||||
style: textStyle,
|
||||
maxLines: 1,
|
||||
),
|
||||
Text(subtitle ?? filterMatch!,
|
||||
Text(subtitle,
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: Theme.of(context)
|
||||
|
|
@ -175,8 +175,8 @@ class ExpenseListItem extends StatelessWidget {
|
|||
),
|
||||
SizedBox(width: 8),
|
||||
Text(
|
||||
formatNumber(expense!.grossAmount, context,
|
||||
currencyId: expense!.currencyId)!,
|
||||
formatNumber(expense.grossAmount, context,
|
||||
currencyId: expense.currencyId)!,
|
||||
style: textStyle,
|
||||
textAlign: TextAlign.end,
|
||||
),
|
||||
|
|
@ -188,10 +188,10 @@ class ExpenseListItem extends StatelessWidget {
|
|||
)
|
||||
: ListTile(
|
||||
onTap: () =>
|
||||
onTap != null ? onTap!() : selectEntity(entity: expense!),
|
||||
onTap != null ? onTap!() : selectEntity(entity: expense),
|
||||
onLongPress: () => onTap != null
|
||||
? null
|
||||
: selectEntity(entity: expense!, longPress: true),
|
||||
: selectEntity(entity: expense, longPress: true),
|
||||
leading: showCheckbox
|
||||
? IgnorePointer(
|
||||
ignoring: listUIState.isInMultiselect(),
|
||||
|
|
@ -210,17 +210,17 @@ class ExpenseListItem 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!.amount, context,
|
||||
currencyId: expense!.currencyId)!,
|
||||
formatNumber(expense.amount, context,
|
||||
currencyId: expense.currencyId)!,
|
||||
style: Theme.of(context).textTheme.titleMedium),
|
||||
],
|
||||
),
|
||||
|
|
@ -247,14 +247,14 @@ class ExpenseListItem extends StatelessWidget {
|
|||
),
|
||||
Text(
|
||||
localization!.lookup(
|
||||
kExpenseStatuses[expense!.calculatedStatusId])!,
|
||||
kExpenseStatuses[expense.calculatedStatusId])!,
|
||||
style: TextStyle(
|
||||
color: category.color.isNotEmpty &&
|
||||
category.color != '#fff'
|
||||
? convertHexStringToColor(category.color)
|
||||
: ExpenseStatusColors(
|
||||
state.prefState.colorThemeModel)
|
||||
.colors[expense!.calculatedStatusId])),
|
||||
.colors[expense.calculatedStatusId])),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -456,19 +456,19 @@ class _InvoiceEditItemsDesktopState extends State<InvoiceEditItemsDesktop> {
|
|||
overflow: TextOverflow.ellipsis,
|
||||
);
|
||||
} else if (column == COLUMN_CUSTOM1) {
|
||||
return Text(item.customValue1 ?? '');
|
||||
return Text(item.customValue1);
|
||||
} else if (column == COLUMN_CUSTOM2) {
|
||||
return Text(item.customValue2 ?? '');
|
||||
return Text(item.customValue2);
|
||||
} else if (column == COLUMN_CUSTOM3) {
|
||||
return Text(item.customValue3 ?? '');
|
||||
return Text(item.customValue3);
|
||||
} else if (column == COLUMN_CUSTOM4) {
|
||||
return Text(item.customValue4 ?? '');
|
||||
return Text(item.customValue4);
|
||||
} else if (column == COLUMN_TAX1) {
|
||||
return Text(item.taxName1 ?? '');
|
||||
return Text(item.taxName1);
|
||||
} else if (column == COLUMN_TAX2) {
|
||||
return Text(item.taxName2 ?? '');
|
||||
return Text(item.taxName2);
|
||||
} else if (column == COLUMN_TAX3) {
|
||||
return Text(item.taxName3 ?? '');
|
||||
return Text(item.taxName3);
|
||||
} else if (column == COLUMN_TAX_CATEGORY) {
|
||||
return Text(localization
|
||||
.lookup(kTaxCategories[item.taxCategoryId])!);
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ class InvoiceEditVM extends AbstractInvoiceEditVM {
|
|||
for (int i = 0; i < invoice.lineItems.length; i++) {
|
||||
final lineItem = invoice.lineItems[i]!;
|
||||
final task = state.taskState.get(lineItem.taskId ?? '');
|
||||
if ((task.clientId ?? '').isNotEmpty && task.clientId != clientId) {
|
||||
if (task.clientId.isNotEmpty && task.clientId != clientId) {
|
||||
showDialog<ErrorDialog>(
|
||||
context: navigatorKey.currentContext!,
|
||||
builder: (BuildContext context) {
|
||||
|
|
@ -204,8 +204,8 @@ class InvoiceEditVM extends AbstractInvoiceEditVM {
|
|||
if ((clientId ?? '').isNotEmpty || (projectId ?? '').isNotEmpty) {
|
||||
final client = state.clientState.get(clientId!);
|
||||
store.dispatch(UpdateInvoice(invoice.rebuild((b) => b
|
||||
..clientId = clientId ?? ''
|
||||
..projectId = projectId ?? ''
|
||||
..clientId = clientId
|
||||
..projectId = projectId
|
||||
..invitations.replace(BuiltList<InvitationEntity>(client
|
||||
.emailContacts
|
||||
.map(
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ class InvoiceListItem extends StatelessWidget {
|
|||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
(invoice.number ?? '').isEmpty
|
||||
invoice.number.isEmpty
|
||||
? localization.pending
|
||||
: invoice.number,
|
||||
style: textStyle,
|
||||
|
|
@ -236,7 +236,7 @@ class InvoiceListItem extends StatelessWidget {
|
|||
children: <Widget>[
|
||||
Expanded(
|
||||
child: filterMatch == null
|
||||
? Text((((invoice.number ?? '').isEmpty
|
||||
? Text(((invoice.number.isEmpty
|
||||
? localization.pending
|
||||
: invoice.number) +
|
||||
' • ' +
|
||||
|
|
|
|||
|
|
@ -79,9 +79,8 @@ class InvoicePresenter extends EntityPresenter {
|
|||
case InvoiceFields.status:
|
||||
return EntityStatusChip(entity: invoice, showState: true);
|
||||
case InvoiceFields.number:
|
||||
return Text((invoice.number ?? '').isEmpty
|
||||
? localization!.pending
|
||||
: invoice.number);
|
||||
return Text(
|
||||
invoice.number.isEmpty ? localization!.pending : invoice.number);
|
||||
case InvoiceFields.client:
|
||||
return LinkTextRelatedEntity(entity: client, relation: invoice);
|
||||
case InvoiceFields.project:
|
||||
|
|
@ -203,7 +202,7 @@ class InvoicePresenter extends EntityPresenter {
|
|||
return Text(localization!.secondReminder);
|
||||
} else if ((invoice.reminder1Sent ?? '').isNotEmpty) {
|
||||
return Text(localization!.firstReminder);
|
||||
} else if ((invoice.lastSentDate ?? '').isNotEmpty) {
|
||||
} else if (invoice.lastSentDate.isNotEmpty) {
|
||||
return Text(localization!.initialEmail);
|
||||
} else {
|
||||
return Text('');
|
||||
|
|
|
|||
|
|
@ -264,12 +264,12 @@ class InvoiceOverview extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
|
||||
if ((invoice.projectId ?? '').isNotEmpty) {
|
||||
if (invoice.projectId.isNotEmpty) {
|
||||
final project = state.projectState.get(invoice.projectId);
|
||||
widgets.add(EntityListTile(entity: project, isFilter: isFilter));
|
||||
}
|
||||
|
||||
if ((invoice.expenseId ?? '').isNotEmpty) {
|
||||
if (invoice.expenseId.isNotEmpty) {
|
||||
final expense = state.vendorState.get(invoice.expenseId);
|
||||
widgets.add(EntityListTile(entity: expense, isFilter: isFilter));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ class ProjectListItem extends StatelessWidget {
|
|||
? ' 📎'
|
||||
: ''),
|
||||
style: textStyle),
|
||||
Text(subtitle ?? filterMatch!,
|
||||
Text(subtitle,
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: Theme.of(context)
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ class RecurringExpenseListItem extends StatelessWidget {
|
|||
style: textStyle,
|
||||
maxLines: 1,
|
||||
),
|
||||
Text(subtitle ?? filterMatch!,
|
||||
Text(subtitle,
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: Theme.of(context)
|
||||
|
|
|
|||
|
|
@ -706,28 +706,28 @@ class _ReportDataTableState extends State<ReportDataTable> {
|
|||
|
||||
class TotalsDataTable extends StatelessWidget {
|
||||
const TotalsDataTable({
|
||||
this.reportSettings,
|
||||
this.reportResult,
|
||||
this.viewModel,
|
||||
required this.reportSettings,
|
||||
required this.reportResult,
|
||||
required this.viewModel,
|
||||
});
|
||||
|
||||
final ReportsScreenVM? viewModel;
|
||||
final ReportSettingsEntity? reportSettings;
|
||||
final ReportResult? reportResult;
|
||||
final ReportsScreenVM viewModel;
|
||||
final ReportSettingsEntity reportSettings;
|
||||
final ReportResult reportResult;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return mt.DataTable(
|
||||
sortColumnIndex:
|
||||
reportResult!.columns.length > reportSettings!.sortTotalsIndex
|
||||
? reportSettings!.sortTotalsIndex
|
||||
reportResult.columns.length > reportSettings.sortTotalsIndex
|
||||
? reportSettings.sortTotalsIndex
|
||||
: null,
|
||||
sortAscending: reportSettings!.sortTotalsAscending ?? true,
|
||||
columns: reportResult!.totalColumns(
|
||||
sortAscending: reportSettings.sortTotalsAscending ?? true,
|
||||
columns: reportResult.totalColumns(
|
||||
context,
|
||||
(index, ascending) =>
|
||||
viewModel!.onReportTotalsSorted(index, ascending)),
|
||||
rows: reportResult!.totalRows(context),
|
||||
viewModel.onReportTotalsSorted(index, ascending)),
|
||||
rows: reportResult.totalRows(context),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ class TaskListItem extends StatelessWidget {
|
|||
overflow: TextOverflow.ellipsis,
|
||||
style: textStyle),
|
||||
Text(
|
||||
subtitle ?? filterMatch!,
|
||||
subtitle,
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: Theme.of(context)
|
||||
|
|
|
|||
|
|
@ -1047,7 +1047,7 @@ class _MatchWithdrawalsState extends State<_MatchWithdrawals> {
|
|||
separatorBuilder: (context, index) => ListDivider(),
|
||||
itemCount: _expenses.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
final expense = _expenses[index];
|
||||
final expense = _expenses[index]!;
|
||||
return ExpenseListItem(
|
||||
expense: expense,
|
||||
showCheckbox: true,
|
||||
|
|
|
|||
Loading…
Reference in New Issue